public static void Sort(
T[] array,
Comparisoncomparison
)
Элементы можно сортировать только через интерфейс IComparer, IComparable.
Вместо 17 методов из .NET 2.0 присутствуют только 8 перегруженных
методов.
пятница, 4 января 2008 г.
Отсутствие сравнения с помощью делегата
Интересно, но в Mono отсутствует возможность сортировки элементов массива с помощью делегата, т.е. отсутствует следующий перегруженный метод Sort объекта Array:
Явное (explicit) и неявное (implicit) пользовательские приведения
Рассмотрим явное и неявное приведения. Предположим, что мы создаем класс, который должен иметь возможность приведения к данному типу, например:
class Test{}
int i=10;
Test t=(Test)i;
string s="222";
Test t1=s;
В представленном примере вначале используется явное приведение, а затем неявное.
Для использования этой возможности приведения необходимо реализовать следующий код в классе Test:
public class Test
{
private int i;
/**
Определяем оператор явного приведения. Он позволяет осуществлять явное приведение от int к Test. Например, int i=10; Test t=(Test)i;.
*/
public static explicit operator Test(int i)
{
return new Test(i);
}
/**
Определям оператор неявного приведения. Он позволяет осуществлять приведение от string к Test.
*/
public static implicit operator Test(string s)
{
int j=Convert.ToInt32(s);
return new Test(j);
}
public Test(int i)
{
this.i=i;
}
public override string ToString()
{
return string.Format("field value: {0}",i);
}
}
Для тестирования приведенного выше класса напишем следующий метод Main:
public static void Main(string[] args)
{
Test t1=(Test)100;
Console.WriteLine("Test: "+t1);
Test t2="222";
Console.WriteLine("Test: "+t2);
}
class Test{}
int i=10;
Test t=(Test)i;
string s="222";
Test t1=s;
В представленном примере вначале используется явное приведение, а затем неявное.
Для использования этой возможности приведения необходимо реализовать следующий код в классе Test:
public class Test
{
private int i;
/**
Определяем оператор явного приведения. Он позволяет осуществлять явное приведение от int к Test. Например, int i=10; Test t=(Test)i;.
*/
public static explicit operator Test(int i)
{
return new Test(i);
}
/**
Определям оператор неявного приведения. Он позволяет осуществлять приведение от string к Test.
*/
public static implicit operator Test(string s)
{
int j=Convert.ToInt32(s);
return new Test(j);
}
public Test(int i)
{
this.i=i;
}
public override string ToString()
{
return string.Format("field value: {0}",i);
}
}
Для тестирования приведенного выше класса напишем следующий метод Main:
public static void Main(string[] args)
{
Test t1=(Test)100;
Console.WriteLine("Test: "+t1);
Test t2="222";
Console.WriteLine("Test: "+t2);
}
Асинхронные делегаты (продолжение)
Рассмотрим более полный пример использования асинхронного делегата. Пусть делегат имеет не 1 параметер, передаваемый по значению, как в прошлом посте, а три. Первый пусть передается по значению, второй параметер имеет модификатор out, а третий - ref.
delegate string TestDelegate(string s, out string s1, ref string s2)
У BeginInvoke и EndInvoke появляются дополнительные параметры, которые необходимо учитывать.
BeginInvoke(string,out string, ref string, AsyncCallback, object);
EndInvoke(out string, ref string, IAsyncResult).
В EndInvoke первые 2 параметра позволяют получать значения, вычисляемые в делегате.
Код примера приведен ниже:
/**
У делегата появились 2 дополнительных параметра по отношению к предыдущему посту.
*/
delegate string TestDelegate(string s, out string s1, ref string s2);
class MainClass
{
private TestDelegate td;
/**
Функция, которая регистрируется нами, имеет 2 дополнительных параметра с модификаторами out и ref. В теле функции происходит задание значений для данных параметров.
*/
public string TestDelegateFunc(string s, out string s1, ref string s2)
{
Thread.Sleep(5000);
s1=string.Format("new s1 value: {0}",s);
s2=string.Format("new s2 value: {0}", s);
return string.Format("Result string: {0}",s);
}
/**
По отношению к предыдущему посту функция изменилась следующим образом:
Через EndInvoke появилась возможность получения 2-х дополнительных параметров,
которые соответсвуют параметрам делегата с модификаторами out и ref соответственно.
*/
public void ResultFunc(IAsyncResult ar)
{
StringBuilder sb=(StringBuilder) ar.AsyncState;
AsyncResult ar1=(AsyncResult)ar;
TestDelegate td1=(TestDelegate)ar1.AsyncDelegate;
string s1;
string s2="";
sb.Append(td1.EndInvoke(out s1, ref s2,ar));
Console.WriteLine("In Result Func: "+sb.ToString()+"; s1: "+s1+"; s2: "+s2);
}
private StringBuilder sb=new StringBuilder("Origin!");
/**
При вызове BeginInvoke появляются еще 2 параметра по отношению к предыдущему посту, которые имеею модификаторы out и ref соответственно.
*/
public void test()
{
td=new TestDelegate(TestDelegateFunc);
string s1;
string s2="";
td.BeginInvoke("Test String",out s1, ref s2, new AsyncCallback(ResultFunc),sb);
}
/**
Код не изменился по отношению к предыдущему посту
*/
public void atEnd()
{
Console.WriteLine("Result value: "+sb.ToString());
}
/**
Код остается без изменения по отношению к предыдущему посту
*/
public static void Main(string[] args)
{
MainClass mc=new MainClass();
mc.test();
Console.WriteLine("Before sleeping");
Thread.Sleep(10000);
Console.WriteLine("After sleeping");
mc.atEnd();
}
}
delegate string TestDelegate(string s, out string s1, ref string s2)
У BeginInvoke и EndInvoke появляются дополнительные параметры, которые необходимо учитывать.
BeginInvoke(string,out string, ref string, AsyncCallback, object);
EndInvoke(out string, ref string, IAsyncResult).
В EndInvoke первые 2 параметра позволяют получать значения, вычисляемые в делегате.
Код примера приведен ниже:
/**
У делегата появились 2 дополнительных параметра по отношению к предыдущему посту.
*/
delegate string TestDelegate(string s, out string s1, ref string s2);
class MainClass
{
private TestDelegate td;
/**
Функция, которая регистрируется нами, имеет 2 дополнительных параметра с модификаторами out и ref. В теле функции происходит задание значений для данных параметров.
*/
public string TestDelegateFunc(string s, out string s1, ref string s2)
{
Thread.Sleep(5000);
s1=string.Format("new s1 value: {0}",s);
s2=string.Format("new s2 value: {0}", s);
return string.Format("Result string: {0}",s);
}
/**
По отношению к предыдущему посту функция изменилась следующим образом:
Через EndInvoke появилась возможность получения 2-х дополнительных параметров,
которые соответсвуют параметрам делегата с модификаторами out и ref соответственно.
*/
public void ResultFunc(IAsyncResult ar)
{
StringBuilder sb=(StringBuilder) ar.AsyncState;
AsyncResult ar1=(AsyncResult)ar;
TestDelegate td1=(TestDelegate)ar1.AsyncDelegate;
string s1;
string s2="";
sb.Append(td1.EndInvoke(out s1, ref s2,ar));
Console.WriteLine("In Result Func: "+sb.ToString()+"; s1: "+s1+"; s2: "+s2);
}
private StringBuilder sb=new StringBuilder("Origin!");
/**
При вызове BeginInvoke появляются еще 2 параметра по отношению к предыдущему посту, которые имеею модификаторы out и ref соответственно.
*/
public void test()
{
td=new TestDelegate(TestDelegateFunc);
string s1;
string s2="";
td.BeginInvoke("Test String",out s1, ref s2, new AsyncCallback(ResultFunc),sb);
}
/**
Код не изменился по отношению к предыдущему посту
*/
public void atEnd()
{
Console.WriteLine("Result value: "+sb.ToString());
}
/**
Код остается без изменения по отношению к предыдущему посту
*/
public static void Main(string[] args)
{
MainClass mc=new MainClass();
mc.test();
Console.WriteLine("Before sleeping");
Thread.Sleep(10000);
Console.WriteLine("After sleeping");
mc.atEnd();
}
}
четверг, 3 января 2008 г.
Использование асинхронных делегатов
Я решил рассмотреть функционал, связанный с асинхронными делегатами. В качестве примера рассмотрим ситуацию, когда используется интерфейс IAsyncResult, а также делегат AsyncCallback:
delegate void AsyncCallback(IAsyncResult). Делегат AsyncCallback используется для обработки результата, получаемого в результате выполнения асинхронного делегата. Т.е. вызываем делегат асинхронно, а через AsyncCallback получаем результат выполнения. Для этого в нем должен вызываться метод EndInvoke.
Я не буду подробно описывать BeginInvoke и EndInvoke, которые хорошо описаны на следующих ресурсах: http://msdn2.microsoft.com и на http://ondotnet.com. Отметим, что эти методы делегата генерируются автоматически для делегата. При этом BeginInvoke имеет параметры, которые совпадают с параметрами делегата. Последние два параметра метода BeginInvoke имеею типы AsyncCallback и object соответственно. Первый служит для регистрации метода обратного вызова, а параметр типа object служит для синхронизации и обмена данными.
Рассмотрим следующи пример кода:
using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;
using System.Text;
namespace asyncdeltest
{
// объявляем делегат
delegate string TestDelegate(string s);
class MainClass
{
private TestDelegate td;
// Функция получает строку и засыпает. Она возвратит нам новую строку, созданную на основе // переданной. Данную функцию мы зарегистрируем на делегате.
public string TestDelegateFunc(string s)
{
Thread.Sleep(5000);
return string.Format("Result string: {0}",s);
}
//Эта функция будет использоваться для получения результата выполнения асинхронного
//делегата, т.е. выполнения функции TestDelegateFunc, приведенной выше.
//Для передачи данных будем использовать поле sb, которое представляет собой объект типа
//StringBuilder. Получить этот объект можно через свойство AsyncState объекта AsyncResult.
// Отметим, что AsyncResult относится к пространству имен System.Runtime.Remoting.Messaging.
// Получитить результат выполнения функции TestDelegateFunc можно вызвав метод
//EndInvoke объекта Delegate, передав в него экземпляр типа IAsyncResult.
public void ResultFunc(IAsyncResult ar)
{
StringBuilder sb=(StringBuilder) ar.AsyncState;
AsyncResult ar1=(AsyncResult)ar;
TestDelegate td1=(TestDelegate)ar1.AsyncDelegate;
sb.Append(td1.EndInvoke(ar));
Console.WriteLine("In Result Func: "+sb.ToString());
}
private StringBuilder sb=new StringBuilder("Origin!");
//Этот метод будем использовать для вызова делегата асинхронно.
public void test()
{
td=new TestDelegate(TestDelegateFunc);
td.BeginInvoke("Test String",new AsyncCallback(ResultFunc),sb);
}
//Метод позволит нам получить содержимое объекта, используемого для обмена данными, т.е.
//поля класса типа StringBuilder.
public void atEnd()
{
Console.WriteLine("Result value: "+sb.ToString());
}
//Непосредственно сам тест. Вызываем делегат асинхронно. После этого уходим в сон
// и ожидаем результата. Проверку результата проводим методом atEnd.
public static void Main(string[] args)
{
MainClass mc=new MainClass();
mc.test();
Console.WriteLine("Before sleeping");
Thread.Sleep(10000);
Console.WriteLine("After sleeping");
mc.atEnd();
}
}
}
delegate void AsyncCallback(IAsyncResult). Делегат AsyncCallback используется для обработки результата, получаемого в результате выполнения асинхронного делегата. Т.е. вызываем делегат асинхронно, а через AsyncCallback получаем результат выполнения. Для этого в нем должен вызываться метод EndInvoke.
Я не буду подробно описывать BeginInvoke и EndInvoke, которые хорошо описаны на следующих ресурсах: http://msdn2.microsoft.com и на http://ondotnet.com. Отметим, что эти методы делегата генерируются автоматически для делегата. При этом BeginInvoke имеет параметры, которые совпадают с параметрами делегата. Последние два параметра метода BeginInvoke имеею типы AsyncCallback и object соответственно. Первый служит для регистрации метода обратного вызова, а параметр типа object служит для синхронизации и обмена данными.
Рассмотрим следующи пример кода:
using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;
using System.Text;
namespace asyncdeltest
{
// объявляем делегат
delegate string TestDelegate(string s);
class MainClass
{
private TestDelegate td;
// Функция получает строку и засыпает. Она возвратит нам новую строку, созданную на основе // переданной. Данную функцию мы зарегистрируем на делегате.
public string TestDelegateFunc(string s)
{
Thread.Sleep(5000);
return string.Format("Result string: {0}",s);
}
//Эта функция будет использоваться для получения результата выполнения асинхронного
//делегата, т.е. выполнения функции TestDelegateFunc, приведенной выше.
//Для передачи данных будем использовать поле sb, которое представляет собой объект типа
//StringBuilder. Получить этот объект можно через свойство AsyncState объекта AsyncResult.
// Отметим, что AsyncResult относится к пространству имен System.Runtime.Remoting.Messaging.
// Получитить результат выполнения функции TestDelegateFunc можно вызвав метод
//EndInvoke объекта Delegate, передав в него экземпляр типа IAsyncResult.
public void ResultFunc(IAsyncResult ar)
{
StringBuilder sb=(StringBuilder) ar.AsyncState;
AsyncResult ar1=(AsyncResult)ar;
TestDelegate td1=(TestDelegate)ar1.AsyncDelegate;
sb.Append(td1.EndInvoke(ar));
Console.WriteLine("In Result Func: "+sb.ToString());
}
private StringBuilder sb=new StringBuilder("Origin!");
//Этот метод будем использовать для вызова делегата асинхронно.
public void test()
{
td=new TestDelegate(TestDelegateFunc);
td.BeginInvoke("Test String",new AsyncCallback(ResultFunc),sb);
}
//Метод позволит нам получить содержимое объекта, используемого для обмена данными, т.е.
//поля класса типа StringBuilder.
public void atEnd()
{
Console.WriteLine("Result value: "+sb.ToString());
}
//Непосредственно сам тест. Вызываем делегат асинхронно. После этого уходим в сон
// и ожидаем результата. Проверку результата проводим методом atEnd.
public static void Main(string[] args)
{
MainClass mc=new MainClass();
mc.test();
Console.WriteLine("Before sleeping");
Thread.Sleep(10000);
Console.WriteLine("After sleeping");
mc.atEnd();
}
}
}
Начало
Приветствую всех! Данный блог будет посвящен программированию c использованием Mono. Часть кода, который не может быть создан пока на Mono, будет приведена с использованием языка C# и платформы .NET корпорации Microsoft. Это связано с неполной совместимостью .NET и Mono.
Подписаться на:
Сообщения (Atom)