1

这可能是不可能的,但我希望它是!

我有一个具有泛型类型范围的方法,并实例化一个List<Func<GenericType>>. 然后我有另一种方法可以接收List<Func<T>>. T我对这种方法一无所知。

示例代码

public void PassFuncs<Item>()
{
  List<Func<Item>> funcs = new List<Func<Item>>();
  RecieveFuncs(funcs);
}
public void RecieveFuncs(List<Func<object>> funcs)
{
  //Do some stuff with funcs
}

我希望它会像使用object代替T一样容易,并且会如此简单。当然,T不是一个object,而是一个Type,因此我不能互换它们。有什么建议或者这是不可能的吗?

4

4 回答 4

4

您可以使您的方法通用:

public void RecieveFuncs<T>(List<Func<T>> funcs)
{
  //Do some stuff with funcs
}

要调用它,您可以T显式声明

public void PassFuncs<Item>()
{
  List<Func<Item>> funcs = new List<Func<Item>>();
  RecieveFuncs<Item>(funcs);
}

或者让类型推断魔法完成它的工作并保持调用原样:

public void PassFuncs<Item>()
{
  List<Func<Item>> funcs = new List<Func<Item>>();
  RecieveFuncs(funcs);  // C# automatically infers T = Item
}
于 2013-01-14T10:40:39.490 回答
3

如果你知道这Item是一个引用类型,你可以使用每个函数的方差(但不是列表):

public void PassFuncs<Item>() where Item : class
{
    List<Func<Item>> funcs = new List<Func<Item>>();
    var tmp = funcs.ConvertAll(func => (Func<object>)func);
    RecieveFuncs(tmp);
}

这将创建一个新列表,但使用原始函数。如果这不可能,您需要添加一个中间函数:

public void PassFuncs<Item>()
{
    List<Func<Item>> funcs = new List<Func<Item>>();
    var tmp = funcs.ConvertAll<Func<object>>(func => () => func());
    RecieveFuncs(tmp);
}
于 2013-01-14T10:43:38.200 回答
3

如果RecieveFuncs由于某种原因你不能通用,你可以使用:

public void PassFuncs<TItem>()
    where TItem:class
{
  List<Func<TItem>> funcs = new List<Func<TItem>>();
  RecieveFuncs(funcs);
}

public void RecieveFuncs(IEnumerable<Func<object>> funcs)
{
  //Do some stuff with funcs
}

这需要一个通用约束来引用 的类型TItem,并且需要一个协变接口,IEnumerable<T>而不是List<T>在接收端。如果您真的想收到一个List<Func<object>>,您可以使用创建一个新列表List<Func<object>>(funcs)

于 2013-01-14T10:44:06.970 回答
0

你可以像这样“投射”Func<Item>Func<object>

public delegate object Func();

public void PassFuncs<Item>()
{
  List<Func<Item>> funcs = new List<Func<Item>>();
  RecieveFuncs(funcs.Select<Func<Item>, Func<object>>(f => () => (object)f())
                    .ToList());
}

public void RecieveFuncs(List<Func<object>> funcs)
{
  //Do some stuff with funcs
}

这适用于引用类型和值类型,尽管它会为值类型设置框。如果您仅使用引用类型,请使用 @CodesInChaos 答案。

于 2013-01-14T10:55:31.970 回答