不允许重载泛型类型参数

本文关键字:泛型类型参数 重载 不允许 | 更新日期: 2023-09-27 18:27:05

这部分是好奇,部分是因为我只是想使用它。如果您有以下定义,编译器不允许这样做,因为它表明成员已经定义。不允许泛型类型参数的独占重载的原因是什么?

void Get<T>() where T: struct {}
void Get<T>() where T: class {}

在我看来,这并没有什么内在的问题。有人可能会争辩说,在定义重叠的情况下,编译器应该选择哪一个并不总是很清楚(但一个常见的解决方案似乎是首先最具体的匹配)。

有人能帮我理解或指出资源,不允许这样做的原因是什么吗?

不允许重载泛型类型参数

Eric Lippert在一篇关于泛型约束和方法签名的博客文章中已经回答了这个问题:http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx

对泛型类型的约束不是CLR中方法签名的一部分,因此不能有两个仅在泛型类型约束上不同的方法。如果没有CLR支持,那么让C#以一种与其他.NET语言兼容的合理方式来支持这些语言将是相当麻烦的。

Nullable<T>上的struct约束非常不幸。像Nullable<String>Nullable<Nullable<Nullable<int>>>这样的东西可能会浪费,但那又怎样呢?将前者框为其内容;取消将其作为其内容的框,并在内容为非null时设置HasValue。如果所有可为null的项都报告HasValue,则将前者框为int;如果内容为非null,则在取消框时设置所有嵌套项的HasValue

否则,我建议您创建一个具有类型参数T的静态泛型类,该类包含一个接受T作为参数的委托属性。该属性应返回私有字段的内容,该字段应初始化为指向一个方法,该方法将检查T的类型,并根据需要将委托设置为structclass版本。

这是我所说的一个例子;这一个使用了各种接口约束,而不是结构/类约束,但同样可以有效地使用相同的原则。

静态类_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(参数);}}