36

我喜欢将泛型类型转换器函数发送给一个方法,但我不知道该怎么做。

这是解释我想要实现的目标的无效语法,问题是我不知道如何将泛型类型与我的函数一起指定:

public void SomeUtility(Func<T><object,T> converter)
{
    var myType = converter<MyType>("foo");
}

编辑(另见我在与劳伦斯的评论中的讨论):通过“通用类型转换器”,我的意思是我想传递一个可以转换为任何强类型 <T> (不是对象)的转换器,所以我的下一行方法可以是:

var myOtherType = converter<MyOtherType>("foo");

我喜欢作为参数传递的委托看起来像这样:

private delegate TOutput myConverterDelegate<TOutput>(object objectToConvert);

现在这更像是一种语法/ C# 探索,为了完成任务,我可能会使用接口来代替,但我确实希望这可以通过 func/delegate 来完成。

4

4 回答 4

29

您不能拥有泛型函数或操作的实例 - 所有类型参数都是预先定义的,并且不能由调用者重新定义。

一种简单的方法是通过依赖向下转换来完全避免多态性:

public void SomeUtility(Func<Type, object, object> converter)
{
    var myType = (MyType)converter(typeof(MyType), "foo");
}

如果你想要类型安全,你需要将类型参数的定义推迟给调用者。您可以通过在接口中编写泛型方法来做到这一点:

public void SomeUtility(IConverter converter)
{
    var myType = converter.Convert<MyType>("foo");
}

interface IConverter
{
   T Convert<T>(object obj);
}

编辑:

如果在调用站点知道“转换器类型”,并且只有这种类型将在实用方法中使用,那么您可以在该方法上定义一个泛型类型并使用它,就像其他海报所建议的那样。

于 2012-09-25T08:31:47.117 回答
17
public void SomeUtility<T>(Func<object, T> converter)
{
    var myType = converter("foo");
}

进而:

SomeUtility(arg => new MyType());

在这种情况下,泛型类型推断将起作用。

于 2012-09-25T08:29:09.680 回答
8

你也需要SomeUtility通用。这样做并修复语法给出:

public void SomeUtility<T>(Func<object,T> converter)
{
    var myType = converter("foo");
}
于 2012-09-25T08:27:55.890 回答
4

您必须在编译时知道 T 类型才能使用它。T 可以在类级别或方法级别指定。

class SomeClass<T> {
    public void SomeUtility(Func<object, T> converter) {
        var myType = converter("foo"); // Already is the T-type that you specified.
    }
}

或者

public void SomeUtility<T>(Func<object, T> converter) {
    var myType = converter("foo"); // Already is the T-type that you specified.
}
于 2012-09-25T08:30:31.360 回答