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