c#泛型方法,可以从泛型类型的类型定义中推断参数的类型
本文关键字:类型 定义 参数 泛型类型 泛型方法 | 更新日期: 2023-09-27 18:06:36
是否有任何方法可以运行以下(不编译)代码?我还没有找到解决这个问题的方法。
public class Factory{
public static T Get<T>(V v)
where T : BaseClass<V> {
T someObject = DIContainer.Resolve<T>();
someObject.Set(v);
}
}
T是一个普通的泛型类型参数,用于定义泛型方法"Get",但有一个类型约束,它本身包含一个泛型。现在,方法应该定义一个参数,该参数的类型由该方法的泛型类型参数定义的泛型类型参数定义。
BaseClass将定义一个方法Set,接收其泛型类型参数类型的实参。
这意味着应该可以调用Factory.Get<A<B>>(someObjectCastableToB);
。
它将通过将方法Get定义为带有v的另一个约束的Get来工作,但随后调用将是Factory.Get<A<B>,B>(....)
,这不是那么好,因为B的声明在那里两次。
谢谢!
与c++模板不同,在c++模板中你可以有"模板模板"或"部分专门化",c#泛型参数只能在声明点进行一次深入,泛型约束只能告诉你关于继承的信息,除此之外什么都没有。如果您希望能够引用一个泛型参数的泛型参数,那么唯一的方法就是,正如您在示例中所做的那样,通过对继承谱系的泛型约束(T : BaseClass<V>
),然后V也必须在泛型签名中标识。你需要如下所示:
public class Factory{
public static T Get<T, V>(V v)
where T : BaseClass<V> {
T someObject = DIContainer.Resolve<T>();
someObject.Set(v);
}
}
我在这里添加的只是泛型参数V到你的方法签名。同样,如果没有基类来锚定V,您将无法对您的情况做很多事情。例如,如果T本身的运行时类型是泛型的,而不是它的基类,那么您就会陷入困境,就像下面的示例一样,它将而不是编译。
public class Factory{
public static T Get<T, V>(V v)
where T : T<V> {
T someObject = DIContainer.Resolve<T>();
someObject.Set(v);
}
}