[英]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.