将Func<T>转换为Func<object>

22

我正在尝试弄清楚如何将 Func<T> 传递给 Func<object> 方法参数:

public void Foo<T>(Func<T> p) where T: class
{
    Foo(p);
}

public void Foo(Func<object> p)
{

}

奇怪的是,它可以在.NET 4.0类库中使用,但在Silverlight 4类库中无法使用。 实际上我想让它在Silverlight中工作,并且我有像Func<T, bool>这样的输入参数。

2个回答

31
这样做就可以了:
public void Foo<T>(Func<T> p) where T : class
{
    Func<object> f = () => p();
    Foo(f);
}

1
如果我有像 Func<T,bool> 这样的输入参数,该怎么办? - Alex Burtsev
1
对于 Func<T, bool> 来说有些不同,因为 T 是一个输入参数,我们需要进行向下转换,像这样:Func<object, bool> f = value => p((T)value);。请注意,这可能无法正常工作,因为很可能是 Foo 方法提供了输入参数,它可能会失败,因为它可能提供了一个无法转换为我们的 Tobject - Steven

12
在针对.NET 4.0的C# 4.0中(即具有协变性),由于从T : classobject存在引用保持转换,因此这是可以的。这是可能的,因为Func<T>实际上被定义为Func<out T>,使其具有协变性。
在以前的C#版本或针对较早版本的.NET的C# 4.0中,您需要按照Steven的答案进行转换。
请注意,您需要使用歧义消除来防止递归!最简单的方法是使用两个方法名称。或者使用Foo((Func<object>)p)

1
由于某些奇怪的原因,在.NET4中它可以工作,但在Silverlight4中无法工作。 - Alex Burtsev
1
@Alex 真的吗?我很惊讶。老实说。 - Marc Gravell
3
在Silverlight 4中,Func被定义为:public delegate TResult Func<TResult>(),因此它不是协变的。 - dcstraw

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接