代码之家  ›  专栏  ›  技术社区  ›  SDReyes

c:func<t,tresult>用于通用方法

  •  5
  • SDReyes  · 技术社区  · 15 年前

    可以创建一个 Func object 什么引用了通用方法?喜欢LINQ OrderBy :

    public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector
    )
    
    6 回复  |  直到 13 年前
        1
  •  20
  •   Dan Tao    15 年前

    如果我正确理解您,您会问是否可以从匿名方法中引用泛型方法。

    答案是肯定的。

    例如,假设您想要一些 Func 返回 IEnumerable<int> 按排序顺序排列的对象(与 OrderBy<int, int> )你可以这样做:

    Func<IEnumerable<int>, Func<int, int>, IOrderedEnumerable<int>> orderByFunc =
        System.Linq.Enumerable.OrderBy<int, int>;
    

    那么你可以用这个 芬克 就像其他人一样:

    int[] ints = new int[] { 1, 3, 5, 4, 7, 2, 6, 9, 8 };
    
    // here you're really calling OrderBy<int, int> --
    // you've just stored its address in a variable of type Func<...>
    foreach (int i in orderByFunc(ints, x => x))
        Console.WriteLine(i);
    

    输出:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    

    另一方面,如果您询问是否可以创建“通用匿名方法”,如:

    Func<T> getDefault<T> = () => default(T);
    

    这取决于你的背景。这可以在以下上下文中完成: T 已经声明为泛型类型参数——即,在泛型类或泛型方法中。(见弗雷迪·里奥斯的回答)不幸的是,在这种情况下,这是非法的。

        2
  •  4
  •   eglasius    15 年前

    是的,但这取决于上下文——如果您已经在使用泛型,只需在上下文中使用t/如果没有,那么您已经知道特定的类型。在后面的例子中,如果您需要在一个方法上重用一些逻辑,那么您可能已经受益于将其转移到一个方法中了,所以就像下面的第二个例子一样。

    2个样本:

    public T Something<T>() {
        Func<T> someFunc = () => { return default(T); };
        return someFunc();
    }
    
    public Func<T> GetDefaultCreator<T>() {
        return () => { return default(T); };
    }
    
        3
  •  0
  •   CubanX    15 年前

    像这样?

    Func<Nullable<int>, string> myFunc = c => c.HasValue ? c.ToString() : "null";

    它可以成功地编译,并且可以将任何函数赋给接受可空值并返回字符串的函数。

        4
  •  0
  •   Omnia9    15 年前

    我做过类似的事情:

    public static class Helper{
    
    public static IEnumerable<KeyValuePair<string, string>> ToPairs(this NameValueCollection Form)
            {
                return Form.AllKeys.Cast<string>()
                    .Select(key => new KeyValuePair<string, string>(key, Form[key]));
            }
    }
    

    在C Web开发中,此方法已成为request.form的扩展方法。

        5
  •  0
  •   Rubys    15 年前

    我想我明白了:给定函数 static TResult DoSomeStuff<T, TResult>(T obj) ,可以创建一个 Func<T, TResult> 这样它将引用上面的函数,在创建对它的引用时没有给定类型参数。
    我认为这是可行的(欢迎你来测试它,目前我身边没有C):

    class UselessClass<T, TResult>
    {
       // If it's a static method, this is fine:
        public Func<T, TResult> DaFunc = RelevantClass.DoSomeStuff<T, TResult>;
        // If not, something like this is needed:
        public UselessClass(SomeClassWhereTheFunctionIs from)
        {
           DaFunc = from.DoSomeStuff<T, TResult>;
        }
    }
    

    而且,在orderby中,它实际上不是一般委托。它是一个变量的声明。将函数赋给它时,将从中推断类型。

        6
  •  0
  •   Amir Ismail    13 年前

    可以,但您需要指定类型参数

    func<int> f = myClass.returnsT<int>;
    

    哪里

    class myClass
    {
       T returnsT<T>()
       {...}
    }
    

    如果没有类型参数,它将无法工作