C# 将无约束泛型类型参数传递给约束方法

C# 将无约束泛型类型参数传递给约束方法,c#,generics,type-constraints,C#,Generics,Type Constraints,我有太多的方法: public TValueType? DoStuffWithValueType<TValueType>(int x, int y) where TValueType: struct {} public TRefType DoStuffWithRefType<TRefType>(int x, int y) where TRefType: class {} 我已经尝试过重载DoStuff,但此尝试失败,因为泛型约束不是方法签名的一部分。

我有太多的方法:

public TValueType? DoStuffWithValueType<TValueType>(int x, int y) 
   where TValueType: struct {}

public TRefType DoStuffWithRefType<TRefType>(int x, int y) 
   where TRefType: class {} 
我已经尝试过重载
DoStuff
,但此尝试失败,因为泛型约束不是方法签名的一部分。
我也尝试过摆脱约束,但无法


有什么想法吗?谢谢大家!

基本上,你不能这样做——你必须用反射调用相关的方法,这很难看

当然,您可以使用动态键入来执行此操作,这会对您隐藏反射:

public T DoStuff<T>(int x, int y) {
   dynamic d = this;
   if(typeof(T).IsValueType)
   {
       return d.DoStuffWithValueType<T>(x, y);
   }    
   return d.DoStuffWithRefType<T>(x, y);
}
publictdostuff(intx,inty){
动态d=此;
if(类型(T).IsValueType)
{
返回d.DoStuffWithValueType(x,y);
}    
返回d.dostufwithreftype(x,y);
}
您可能认为这比使用反射手动执行更干净,或者您可能不这么认为:)


我所知道的是,没有办法让编译器“信任”一个通常不会这样做的类型参数。

除了Jon Skeet使用的
动态
,这是我能想到的最干净的方式,最小化所需的反射,从而尽可能多地由编译器验证,是通过助手类调用该方法

abstract class DoStuffHelper<T> {
    public abstract T DoStuff(int x, int y);
}

class DoStuffWithValueTypeHelper<T> : DoStuffHelper<T> where T : struct {
    public override T DoStuff(int x, int y) {
        return DoStuffWithValueType<T>(x, y);
    }
}

class DoStuffWithRefTypeHelper<T> : DoStuffHelper<T> where T : class {
    public override T DoStuff(int x, int y) {
        return DoStuffWithRefType<T>(x, y);
    }
}

public T DoStuff<T>(int x, int y) {
   DoStuffHelper<T> helper;
   Type helperType;

   if(typeof(T).IsValueType)
       helperType = typeof(DoStuffWithValueTypeHelper<>);
   else
       helperType = typeof(DoStuffWithRefTypeHelper<>);

   helperType = helperType.MakeGenericType(typeof(T));
   helper = (DoStuffHelper<T>)Activator.CreateInstance(helperType);

   return helper.DoStuff(x, y);
}
抽象类DoStuffHelper{
公共摘要T DoStuff(int x,int y);
}
类DoStuffWithValueTypeHelper:DoStuffHelper,其中T:struct{
公共覆盖T DoStuff(整数x,整数y){
返回DoStuffWithValueType(x,y);
}
}
类DoStuffWithRefTypeHelper:DoStuffHelper,其中T:class{
公共覆盖T DoStuff(整数x,整数y){
返回DoStuffWithRefType(x,y);
}
}
公共交通线(内线x,内线y){
多斯塔夫助手;
类型helperType;
if(类型(T).IsValueType)
helperType=typeof(dostufwithvaluetypehelper);
其他的
helperType=typeof(dostufwithreftypehelper);
helperType=helperType.MakeGenericType(typeof(T));
helper=(DoStuffHelper)Activator.CreateInstance(helperType);
返回helper.DoStuff(x,y);
}

如果适合您的情况,您可以在
字典中缓存helper类
,以避免每次都重新创建它们。

只是提前警告:类型是值类型的事实并不一定意味着它是
结构
约束的有效泛型类型参数。可空值类型不能与
结构
约束一起使用。谢谢!没想到像你这样的名人会回答我的问题;)
abstract class DoStuffHelper<T> {
    public abstract T DoStuff(int x, int y);
}

class DoStuffWithValueTypeHelper<T> : DoStuffHelper<T> where T : struct {
    public override T DoStuff(int x, int y) {
        return DoStuffWithValueType<T>(x, y);
    }
}

class DoStuffWithRefTypeHelper<T> : DoStuffHelper<T> where T : class {
    public override T DoStuff(int x, int y) {
        return DoStuffWithRefType<T>(x, y);
    }
}

public T DoStuff<T>(int x, int y) {
   DoStuffHelper<T> helper;
   Type helperType;

   if(typeof(T).IsValueType)
       helperType = typeof(DoStuffWithValueTypeHelper<>);
   else
       helperType = typeof(DoStuffWithRefTypeHelper<>);

   helperType = helperType.MakeGenericType(typeof(T));
   helper = (DoStuffHelper<T>)Activator.CreateInstance(helperType);

   return helper.DoStuff(x, y);
}