简体   繁体   中英

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. 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.
Meaning it should be possible to call 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.

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. 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. 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. Again, if you had no base class to anchor V to, you wouldn't be able to do much about your situation. 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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