繁体   English   中英

将不受约束的泛型类型参数传递给受约束的方法

[英]Passing unconstrained generic type parameter to a constrained method

我也有方法:

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

public TRefType DoStuffWithRefType<TRefType>(int x, int y) 
   where TRefType: class {} 

我如何用新的第三种方法包装它们?

以下内容未编译,因为在调用DoStuffWithValueType时我无法说服编译器T实际上是一个结构:

public T DoStuff<T>(int x, int y) {

   if(typeof(T).IsValueType)
   {
      return DoStuffWithValueType<T>(x, y);
   }

   return DoStuffWithRefType<T>(x, y);
}

我已经尝试重载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);
}

您可能认为这样做比使用反射手动进行清理更清洁-否则您可能不会:)

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

除了Jon Skeet使用dynamic ,我能想到的最简洁的方法是最大程度地减少所需的反射,从而使编译器尽可能多地进行验证,这是通过助手类调用该方法。

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);
}

如果适合您的情况,可以将辅助程序类缓存在Dictionary<Type, object>以避免每次都重新创建它们。

暂无
暂无

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

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