C# 如何传入带有泛型类型参数的 func?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12578965/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I pass in a func with a generic type parameter?
提问by joeriks
I like to send a generic type converter function to a method but I can't figure out how to do it.
我喜欢向一个方法发送一个泛型类型转换器函数,但我不知道如何去做。
Here's invalid syntax that explains what I like to achieve, the problem is I don't know how to specify the generic type together with my func:
这是解释我想要实现的无效语法,问题是我不知道如何与我的 func 一起指定泛型类型:
public void SomeUtility(Func<T><object,T> converter)
{
var myType = converter<MyType>("foo");
}
Edit (see also my discussion in the comments with Lawrence) : By "generic type converter" I meant I would like to pass in a converter that can convert to any strong type <T> (not object), so the next line in my method could be:
编辑(另请参阅我在与 Lawrence 的评论中的讨论):通过“通用类型转换器”,我的意思是我想传入一个可以转换为任何强类型 <T>(不是对象)的转换器,因此我的下一行方法可以是:
var myOtherType = converter<MyOtherType>("foo");
The delegate I like to pass as a parameter would look something like this:
我喜欢作为参数传递的委托看起来像这样:
private delegate TOutput myConverterDelegate<TOutput>(object objectToConvert);
This is more a syntax / C# exploration now, to get things done I will probably use an interface instead, but I do hope this is possible to accomplish with a func/delegate.
现在这更像是一种语法/C# 探索,为了完成工作,我可能会使用接口来代替,但我确实希望这可以通过 func/delegate 来完成。
采纳答案by Lawrence Wagerfield
You cannot have instances of generic functions or actions - all type parameters are defined upfront and cannot be redefined by the caller.
您不能拥有通用函数或操作的实例 - 所有类型参数都是预先定义的,并且不能由调用者重新定义。
An easy way would be to avoid polymorphism altogether by relying on down-casting:
一种简单的方法是通过依赖向下转换来完全避免多态性:
public void SomeUtility(Func<Type, object, object> converter)
{
var myType = (MyType)converter(typeof(MyType), "foo");
}
If you want type safety, you need to defer the definition of the type parameters to the caller. You can do this by composing a generic method within an interface:
如果你想要类型安全,你需要将类型参数的定义推迟到调用者。您可以通过在接口中组合一个泛型方法来做到这一点:
public void SomeUtility(IConverter converter)
{
var myType = converter.Convert<MyType>("foo");
}
interface IConverter
{
T Convert<T>(object obj);
}
Edit:
编辑:
If the 'converter type' is known at the call-site, and only this type will be used inside the utility method, then you can define a generic type on the method and use that, just like other posters have suggested.
如果在调用站点知道“转换器类型”,并且在实用程序方法中只使用这种类型,那么您可以在该方法上定义一个泛型类型并使用它,就像其他海报所建议的那样。
回答by Jon
You need to make SomeUtilitygeneric as well. Doing this and fixing the syntax gives:
你也需要SomeUtility通用。这样做并修复语法给出:
public void SomeUtility<T>(Func<object,T> converter)
{
var myType = converter("foo");
}
回答by Darin Dimitrov
public void SomeUtility<T>(Func<object, T> converter)
{
var myType = converter("foo");
}
and then:
进而:
SomeUtility(arg => new MyType());
The generic type inference will work in this case.
在这种情况下,泛型类型推断将起作用。
回答by Maarten
You have to know the T type at compile-time to use it. The T can either be specified at class-level or at method-level.
您必须在编译时知道 T 类型才能使用它。T 可以在类级别或方法级别指定。
class SomeClass<T> {
public void SomeUtility(Func<object, T> converter) {
var myType = converter("foo"); // Already is the T-type that you specified.
}
}
or
或者
public void SomeUtility<T>(Func<object, T> converter) {
var myType = converter("foo"); // Already is the T-type that you specified.
}

