Jon*_*eet 100
既然我们在C#中有lambda表达式和匿名方法,我就更多地使用委托了.在C#1中,你总是需要一个单独的方法来实现逻辑,使用委托通常没有意义.这些天我使用代表:
And*_*are 28
代表们在很多方面非常有用.
一个这样的目的是使用它们来过滤数据序列.在这种情况下,您将使用谓词委托,该委托接受一个参数并根据委托本身的实现返回true或false.
这是一个愚蠢的例子 - 我相信你可以推断一些更有用的东西:
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<String> names = new List<String>
{
"Nicole Hare",
"Michael Hare",
"Joe Hare",
"Sammy Hare",
"George Washington",
};
// Here I am passing "inMyFamily" to the "Where" extension method
// on my List<String>. The C# compiler automatically creates
// a delegate instance for me.
IEnumerable<String> myFamily = names.Where(inMyFamily);
foreach (String name in myFamily)
Console.WriteLine(name);
}
static Boolean inMyFamily(String name)
{
return name.EndsWith("Hare");
}
}
Run Code Online (Sandbox Code Playgroud)
Max*_*ler 13
找到另一个有趣的答案
一位同事刚刚问我这个问题 - .NET代表的观点是什么?我的答案很短,而且他没有在网上找到的答案:推迟执行方法.
资料来源:LosTechies
就像LINQ一样.
har*_*rpo 12
您可以使用委托来声明函数类型的变量和参数.
例
考虑"资源借用"模式.您希望控制资源的创建和清理,同时允许客户端代码在其间"借用"资源.
这声明了一个委托类型.
public delegate void DataReaderUser( System.Data.IDataReader dataReader );
Run Code Online (Sandbox Code Playgroud)
匹配此签名的任何方法都可用于实例化此类型的委托.在C#2.0中,这可以通过使用方法的名称以及使用匿名方法隐式完成.
此方法使用类型作为参数.请注意委托的调用.
public class DataProvider
{
protected string _connectionString;
public DataProvider( string psConnectionString )
{
_connectionString = psConnectionString;
}
public void UseReader( string psSELECT, DataReaderUser readerUser )
{
using ( SqlConnection connection = new SqlConnection( _connectionString ) )
try
{
SqlCommand command = new SqlCommand( psSELECT, connection );
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while ( reader.Read() )
readerUser( reader ); // the delegate is invoked
}
catch ( System.Exception ex )
{
// handle exception
throw ex;
}
}
}
Run Code Online (Sandbox Code Playgroud)
可以使用匿名方法调用该函数,如下所示.请注意,匿名方法可以使用在其自身之外声明的变量.这非常方便(虽然这个例子有点人为).
string sTableName = "test";
string sQuery = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='" + sTableName + "'";
DataProvider.UseReader( sQuery,
delegate( System.Data.IDataReader reader )
{
Console.WriteLine( sTableName + "." + reader[0] );
} );
Run Code Online (Sandbox Code Playgroud)
jon*_*nii 10
通常可以使用代理来代替具有一种方法的接口,这种情况的一个常见示例是观察者模式.在其他语言中,如果您希望收到发生某些事情的通知,您可以定义如下内容:
class IObserver{ void Notify(...); }
Run Code Online (Sandbox Code Playgroud)
在C#中,这通常使用事件表示,其中处理程序是委托,例如:
myObject.SomeEvent += delegate{ Console.WriteLine("..."); };
Run Code Online (Sandbox Code Playgroud)
如果必须将谓词传递给函数,例如从列表中选择一组项时,另一个使用委托的好地方:
myList.Where(i => i > 10);
Run Code Online (Sandbox Code Playgroud)
上面是lambda语法的一个例子,它也可以写成如下:
myList.Where(delegate(int i){ return i > 10; });
Run Code Online (Sandbox Code Playgroud)
使用委托可能有用的另一个地方是注册工厂功能,例如:
myFactory.RegisterFactory(Widgets.Foo, () => new FooWidget());
var widget = myFactory.BuildWidget(Widgets.Foo);
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助!
wil*_*ill 10
我很晚才进入这个阶段,但是我今天很难弄清楚代表们的目的,并编写了两个简单的程序,这些程序提供了相同的输出,我认为它很好地解释了它们的用途.
NoDelegates.cs
using System;
public class Test {
public const int MAX_VALUE = 255;
public const int MIN_VALUE = 10;
public static void checkInt(int a) {
Console.Write("checkInt result of {0}: ", a);
if (a < MAX_VALUE && a > MIN_VALUE)
Console.WriteLine("max and min value is valid");
else
Console.WriteLine("max and min value is not valid");
}
public static void checkMax(int a) {
Console.Write("checkMax result of {0}: ", a);
if (a < MAX_VALUE)
Console.WriteLine("max value is valid");
else
Console.WriteLine("max value is not valid");
}
public static void checkMin(int a) {
Console.Write("checkMin result of {0}: ", a);
if (a > MIN_VALUE)
Console.WriteLine("min value is valid");
else
Console.WriteLine("min value is not valid");
Console.WriteLine("");
}
}
public class Driver {
public static void Main(string [] args) {
Test.checkInt(1);
Test.checkMax(1);
Test.checkMin(1);
Test.checkInt(10);
Test.checkMax(10);
Test.checkMin(10);
Test.checkInt(20);
Test.checkMax(20);
Test.checkMin(20);
Test.checkInt(30);
Test.checkMax(30);
Test.checkMin(30);
Test.checkInt(254);
Test.checkMax(254);
Test.checkMin(254);
Test.checkInt(255);
Test.checkMax(255);
Test.checkMin(255);
Test.checkInt(256);
Test.checkMax(256);
Test.checkMin(256);
}
}
Run Code Online (Sandbox Code Playgroud)
Delegates.cs
using System;
public delegate void Valid(int a);
public class Test {
public const int MAX_VALUE = 255;
public const int MIN_VALUE = 10;
public static void checkInt(int a) {
Console.Write("checkInt result of {0}: ", a);
if (a < MAX_VALUE && a > MIN_VALUE)
Console.WriteLine("max and min value is valid");
else
Console.WriteLine("max and min value is not valid");
}
public static void checkMax(int a) {
Console.Write("checkMax result of {0}: ", a);
if (a < MAX_VALUE)
Console.WriteLine("max value is valid");
else
Console.WriteLine("max value is not valid");
}
public static void checkMin(int a) {
Console.Write("checkMin result of {0}: ", a);
if (a > MIN_VALUE)
Console.WriteLine("min value is valid");
else
Console.WriteLine("min value is not valid");
Console.WriteLine("");
}
}
public class Driver {
public static void Main(string [] args) {
Valid v1 = new Valid(Test.checkInt);
v1 += new Valid(Test.checkMax);
v1 += new Valid(Test.checkMin);
v1(1);
v1(10);
v1(20);
v1(30);
v1(254);
v1(255);
v1(256);
}
}
Run Code Online (Sandbox Code Playgroud)
稍微不同的用途是加速反射; 即,不是每次都使用反射,您可以使用Delegate.CreateDelegate创建方法(a MethodInfo)的(类型)委托,并调用该委托.然后,每次调用都会更快,因为检查已经完成.
有了Expression,您也可以动态创建代码 - 例如,您可以轻松地创建一个Expression代表运算符选择的类型的+运算符(为泛型提供操作员支持,语言不提供) ; 你可以编译Expression一个类型的委托 - 完成工作.
任何时候使用事件都会使用代理 - 这是它们工作的机制.
此外,委托对于使用LINQ查询等内容非常有用.例如,许多LINQ查询采用Func<T,TResult>可以用于过滤的委托(通常).