我也有方法:
public TValueType? DoStuffWithValueType<TValueType>(int x, int y)
where TValueType: struct {}
public TRefType DoStuffWithRefType<TRefType>(int x, int y)
where TRefType: class {}
我如何用新的第三种方法包装它们?
以下是没有编译的,因为我无法说服编译器T
在调用DoStuffWithValueType
时实际上是一个结构:
public T DoStuff<T>(int x, int y) {
if(typeof(T).IsValueType)
{
return DoStuffWithValueType<T>(x, y);
}
return DoStuffWithRefType<T>(x, y);
}
我已经尝试重载DoStuff
,但是这次尝试失败了,因为泛型约束不是方法签名的一部分。
我也试图摆脱约束,但我不能。
有什么想法吗?谢谢!
答案 0 :(得分:2)
基本上你不能用反射来调用相关的方法,这很难看。
当然,您可以使用动态类型来执行此操作,这会隐藏您的反射:
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);
}
您可能认为比使用反射手动更清洁 - 或者您可能不会:)
我不知道如何使编译器和#34;信任&#34;一个类型参数,它通常不会这样做。
答案 1 :(得分:1)
除了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>
中缓存帮助程序类,以避免每次都重新创建它们。