【问题标题】:How can I write a generic anonymous method?如何编写通用匿名方法?
【发布时间】:2010-12-02 19:23:25
【问题描述】:

具体来说,我想这样写:

public Func<IList<T>, T> SelectElement = list => list.First();

但我在T 收到语法错误。我不能有一个通用的匿名方法吗?

【问题讨论】:

标签: c# generics anonymous-function


【解决方案1】:

不,对不起。这将需要通用字段或通用属性,这些不是 C# 支持的功能。您能做的最好的事情是创建一个引入 T 的通用方法:

public Func<IList<T>, T> SelectionMethod<T>() { return list => list.First(); }

现在你可以说:

Func<IList<int>, int> selectInts = SelectionMethod<int>();

【讨论】:

    【解决方案2】:

    当然可以,但必须知道T

    class Foo<T>
    {
        public Func<IList<T>, T> SelectionMethod = list => list.First();
    }
    

    如果您不想将包含的类设为通用,则可以使用通用方法:

    public Func<IList<T>, T> SelectionMethod<T>()
    {
        return list => list.First();
    }
    

    但是在编译时仍然需要有人知道这个T

    【讨论】:

    • 是的..这就是问题所在。我不知道T是什么。它可以是字符或字符串。
    • 那么希望Foo&lt;T&gt; 类的消费者(实例化它的那个)会知道它。如果您在编译时不知道它,那么泛型不是适合您的工件。
    • 那么您的方法或您的类必须采用泛型参数T
    • 另一个问题是我希望用户能够覆盖选择方法,这就是我将它作为匿名函数的原因:) 当我调用此方法时,我知道T 是什么,但我在 2 个不同的地方使用它(一次在 List 上,一次在 List 上),我想对两者使用相同的方法。
    • 所以如果用户应该修改这个字段(不是属性),你为什么不给他一个通用的方法来接受委托:public void DoSomething&lt;T&gt;(Func&lt;IList&lt;T&gt;, T&gt; foo) { ... }。现在,当用户调用此方法时,他可以将任何他喜欢的表达式作为参数传递:DoSomething(x =&gt; x.First()); 并在方法内部您将完成这项工作。您甚至可以提供此方法的重载,该方法将执行.First() 的工作:public void DoSomething&lt;T&gt;() { ... },您将在其中构造一个匿名委托。
    【解决方案3】:

    您仅将返回类型声明为泛型。

    试试这个:

    public Func<IList<T>, T> SelectionMethod<T>() { return list => list.First(); }
    

    您要声明的事物的名称必须包含类型参数才能使其成为泛型。编译器仅支持泛型类和泛型方法。

    所以,对于一个泛型类,你必须有

    class MyGeneric<T> { 
       // You can use T here now
       public T MyField;
     }
    

    或者,对于方法

    public T MyGenericMethod<T>( /* Parameters */ ) { return T; }
    

    您可以使用 T 作为返回参数,前提是它首先在方法名称中声明。

    尽管看起来返回类型是在实际方法之前声明的,但编译器不会这样读取它。

    【讨论】:

    • 嗯?不,我没有……甚至在编辑之前。这与什么有什么关系?
    • 这是一个更好的解释。我想要一个通用的 lambda,但我猜它不存在。
    【解决方案4】:
        public static void SomeContainerFunction()
        {
            const string NULL_VALUE = (string)null;
    
            Type GetValueType<T>(T value) => value?.GetType() ?? typeof(T);
    
            var typeOfNullValue = GetValueType(NULL_VALUE);
    
            Debug.WriteLine($"Value: {NULL_VALUE}, Type: {typeOfNullValue}");
        }
    

    【讨论】:

    • 欢迎来到 SO。回答问题时,请提供与您的代码相关的解释。有些人可能不理解您的代码或看不到它如何回答问题。见how to write a good answer
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多