不允许重载泛型类型参数
本文关键字:泛型类型参数 重载 不允许 | 更新日期: 2023-09-27 18:27:05
这部分是好奇,部分是因为我只是想使用它。如果您有以下定义,编译器不允许这样做,因为它表明成员已经定义。不允许泛型类型参数的独占重载的原因是什么?
void Get<T>() where T: struct {}
void Get<T>() where T: class {}
在我看来,这并没有什么内在的问题。有人可能会争辩说,在定义重叠的情况下,编译器应该选择哪一个并不总是很清楚(但一个常见的解决方案似乎是首先最具体的匹配)。
有人能帮我理解或指出资源,不允许这样做的原因是什么吗?
对泛型类型的约束不是CLR中方法签名的一部分,因此不能有两个仅在泛型类型约束上不同的方法。如果没有CLR支持,那么让C#以一种与其他.NET语言兼容的合理方式来支持这些语言将是相当麻烦的。
Nullable<T>
上的struct
约束非常不幸。像Nullable<String>
或Nullable<Nullable<Nullable<int>>>
这样的东西可能会浪费,但那又怎样呢?将前者框为其内容;取消将其作为其内容的框,并在内容为非null时设置HasValue
。如果所有可为null的项都报告HasValue
,则将前者框为int
;如果内容为非null,则在取消框时设置所有嵌套项的HasValue
。
否则,我建议您创建一个具有类型参数T
的静态泛型类,该类包含一个接受T
作为参数的委托属性。该属性应返回私有字段的内容,该字段应初始化为指向一个方法,该方法将检查T
的类型,并根据需要将委托设置为struct
或class
版本。
这是我所说的一个例子;这一个使用了各种接口约束,而不是结构/类约束,但同样可以有效地使用相同的原则。
静态类_FooDispatcher<T>{公共静态动作<T>Foo=setupFoo;静态空隙doFooWithIGoodFoo<TT>(TT param)其中TT:IGoodFoo{Console.WriteLine("作为{1}类型为{0}的IGoodFoo进行调度",typeof(TT).ToString(),typeof(TT).IsValueType?"value":"reference");参数。Foo();}静态空隙doFooWithIOkayFoo<TT>(TT param)其中TT:IOkayFoo{Console.WriteLine("作为{1}类型为{0}的IOkayFoo进行调度",typeof(TT).ToString(),typeof(TT).IsValueType?"value":"reference");参数。Foo();}static void doFoo不知怎的<TT>(TT参数){Console.WriteLine("{1}类型{0}没有什么令人兴奋的内容",typeof(TT).ToString(),typeof(TT).IsValueType?"value":"reference");}静态无效setupFoo(T参数){System.Reflection.MethodInfo mi;if(typeof(IGoodFoo).IsAssignableFrom(typeofmi=类型(_FooDispatcher<T>).GetMethod("doFooWithIGoodFoo",System.Reflection.BindingFlags.NonPublic|System.Reflection.BindingFlags.Static);否则if(typeof(IOkayFoo).IsAssignableFrom(typeofmi=类型(_FooDispatcher<T>).GetMethod("doFooWithIOkayFoo",System.Reflection.BindingFlags.NonPublic|System.Reflection.BindingFlags.Static);其他的mi=类型为(_FooDispatcher<T>).GetMethod("doFoo莫名其妙",System.Reflection.BindingFlags.NonPublic|System.Reflection.BindingFlags.Static);Foo=(Action<T>)(@Delegate.CreateDelegate(typeof(Action<T>),mi.MakeGenericMethod(typeof;Foo(参数);}}