简体   繁体   English

C#泛型方法,可以从泛型类型的类型定义中推断参数的类型吗?

[英]C# generic methods, possible to infer type for parameters from generic type's type definition?

is there any way to get the following (not compiling) code running? 有什么方法可以使以下(未编译)代码运行? i have not found a solution for this. 我还没有找到解决方案。

public class Factory{
    public static T Get<T>(V v)
        where T : BaseClass<V> {
            T someObject = DIContainer.Resolve<T>();
            someObject.Set(v);
    }
}

T is a normal generic type parameter, used to define the generic method "Get", but has a type constraint which contains a generic itself. T是一个普通的泛型类型参数,用于定义泛型方法“ Get”,但具有类型约束,其中包含泛型本身。 Now the method should define a parameter of which the type is defined by a generic type parameter defined by the generic type parameter of the method. 现在,该方法应该定义一个参数,该类型的类型由该方法的通用类型参数定义的通用类型参数定义。
BaseClass would define a method Set receiving an argument of the type of its generic type parameter. BaseClass将定义一个方法Set,该方法接收其通用类型参数类型的参数。
Meaning it should be possible to call Factory.Get<A<B>>(someObjectCastableToB); 意味着应该可以调用Factory.Get<A<B>>(someObjectCastableToB); .

It would work by defining the method Get as Get with another constraint on V. But then the call would be Factory.Get<A<B>,B>(....) which is not that nice as the declaration of B is there two times. 通过将方法Get as Get定义为V并在V上施加另一个约束将可以工作。但是随后的调用将是Factory.Get<A<B>,B>(....) ,因为B的声明不是那么好有两次。

Thanks! 谢谢!

Unlike C++ templates, where you can have "template templates" or "partial specialization" , C# generic arguments can only go one-deep at the declaration site, and generic constraints can only tell you about lineage and nothing more. 与C ++模板(可以具有“模板模板”“部分专业化”)不同 ,C#泛型参数只能在声明站点上深入了解,泛型约束只能告诉您有关沿袭的信息,仅此而已。 If you want to be able to refer to the generic argument of one of your generic arguments, the only way to do that is, as you have in your example, via a generic constraint on inheritance lineage ( T : BaseClass<V> ), and then V must also be identified in the generic signature. 如果您希望能够引用一个通用参数中的一个通用参数,那么唯一的方法就是通过对继承沿袭( T : BaseClass<V> )的通用约束,如您的示例所示,然后还必须在通用签名中标识V。 You'd need something like below. 您将需要以下类似的东西。

public class Factory{
    public static T Get<T, V>(V v)
        where T : BaseClass<V> {
            T someObject = DIContainer.Resolve<T>();
            someObject.Set(v);
    }
}

All I've added here is the generic argument V to your method signature. 我在这里添加的只是方法签名中的通用参数V。 Again, if you had no base class to anchor V to, you wouldn't be able to do much about your situation. 同样,如果您没有基类来锚定V,那么您将无法做很多事情。 For example, if the runtime type of T itself was generic, and not its base class, you'd be stuck, as in the below sample, which would not compile. 例如,如果T本身的运行时类型是通用类型,而不是其基类,那么您将陷入困境,如以下示例所示,它将无法编译。

public class Factory{
    public static T Get<T, V>(V v)
        where T : T<V> {
            T someObject = DIContainer.Resolve<T>();
            someObject.Set(v);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM