当前位置:  开发笔记 > 编程语言 > 正文

你什么时候在C#中使用代表?

如何解决《你什么时候在C#中使用代表?》经验,为你挑选了8个好方法。

你在C#中对代表的用法是什么?



1> Jon Skeet..:

既然我们在C#中有lambda表达式和匿名方法,我就更多地使用委托了.在C#1中,你总是需要一个单独的方法来实现逻辑,使用委托通常没有意义.这些天我使用代表:

事件处理程序(用于GUI等)

启动线程

回调(例如异步API)

LINQ和类似的(List.Find等)

我希望在其他地方有效地应用"模板"代码,其中包含一些专门的逻辑(代表提供专业化)


+1敢于挑战古老的Skeet先生;-)
我不确定如何简单地解释它而不会让事情变得更加令人困惑:)(可以说,事件处理程序,LINQ和templaty位无论如何它都被覆盖了!
我知道你想说什么,但我会发现以下更容易阅读:"现在我们在C#中有lambda表达式和匿名方法,我更多地使用委托." 我知道我在挑剔,但在对我有意义之前,我真的必须读几遍这句话.

2> Andrew Hare..:

代表们在很多方面非常有用.

一个这样的目的是使用它们来过滤数据序列.在这种情况下,您将使用谓词委托,该委托接受一个参数并根据委托本身的实现返回true或false.

这是一个愚蠢的例子 - 我相信你可以推断一些更有用的东西:

using System;
using System.Linq;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List names = new List
        {
            "Nicole Hare",
            "Michael Hare",
            "Joe Hare",
            "Sammy Hare",
            "George Washington",
        };

        // Here I am passing "inMyFamily" to the "Where" extension method
        // on my List.  The C# compiler automatically creates 
        // a delegate instance for me.
        IEnumerable myFamily = names.Where(inMyFamily);

        foreach (String name in myFamily)
            Console.WriteLine(name);
    }

    static Boolean inMyFamily(String name)
    {
        return name.EndsWith("Hare");
    }
}


`static Boolean inMyFamily(String name)`方法是委托.其中将委托作为参数.当你将方法名称传递给成为委托的`.Where(委托)`时,委托只是函数指针.由于inMyFamily返回一个布尔类型,它实际上被认为是一个谓词.谓词只是返回布尔值的代表.
代表在哪里?
"谓词只是返回布尔值的代表." +1

3> Maxime Rouil..:

找到另一个有趣的答案

一位同事刚刚问我这个问题 - .NET代表的观点是什么?我的答案很短,而且他没有在网上找到的答案:推迟执行方法.

资料来源:LosTechies

就像LINQ一样.



4> harpo..:

您可以使用委托来声明函数类型的变量和参数.

考虑"资源借用"模式.您希望控制资源的创建和清理,同时允许客户端代码在其间"借用"资源.

这声明了一个委托类型.

public delegate void DataReaderUser( System.Data.IDataReader dataReader );

匹配此签名的任何方法都可用于实例化此类型的委托.在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;
        }
    }
}

可以使用匿名方法调用该函数,如下所示.请注意,匿名方法可以使用其自身之外声明的变量.这非常方便(虽然这个例子有点人为).

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] );
    } );



5> jonnii..:

通常可以使用代理来代替具有一种方法的接口,这种情况的一个常见示例是观察者模式.在其他语言中,如果您希望收到发生某些事情的通知,您可以定义如下内容:

class IObserver{ void Notify(...); }

在C#中,这通常使用事件表示,其中处理程序是委托,例如:

myObject.SomeEvent += delegate{ Console.WriteLine("..."); };

如果必须将谓词传递给函数,例如从列表中选择一组项时,另一个使用委托的好地方:

myList.Where(i => i > 10);

上面是lambda语法的一个例子,它也可以写成如下:

myList.Where(delegate(int i){ return i > 10; });

使用委托可能有用的另一个地方是注册工厂功能,例如:

myFactory.RegisterFactory(Widgets.Foo, () => new FooWidget());
var widget = myFactory.BuildWidget(Widgets.Foo);

我希望这有帮助!



6> will..:

我很晚才进入这个阶段,但是我今天很难弄清楚代表们的目的,并编写了两个简单的程序,这些程序提供了相同的输出,我认为它很好地解释了它们的用途.

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);
    }
}

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);
    }
}



7> Marc Gravell..:

稍微不同的用途是加速反射; 即,不是每次都使用反射,您可以使用Delegate.CreateDelegate创建方法(a MethodInfo)的(类型)委托,并调用该委托.然后,每次调用都会更快,因为检查已经完成.

有了Expression,您也可以动态创建代码 - 例如,您可以轻松地创建一个Expression代表运算符选择的类型的+运算符(为泛型提供操作员支持,语言不提供) ; 你可以编译Expression一个类型的委托 - 完成工作.



8> Reed Copsey..:

任何时候使用事件都会使用代理 - 这是它们工作的机制.

此外,委托对于使用LINQ查询等内容非常有用.例如,许多LINQ查询采用Func可以用于过滤的委托(通常).

推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有