【发布时间】:2021-09-17 21:15:34
【问题描述】:
这和这个问题Call overloaded generic method from generic method类似,但不一样:在那种情况下,方法返回void,而我需要返回泛型类型T,所以建议的解决方案不起作用。
我正在实现一个类似元组的类,它具有通用参数和这些参数的访问器:
public class MyClass<T1, T2>
{
private readonly T1 _item1;
private readonly T2 _item2;
public MyClass(T1 item1, T2 item2)
{
_item1 = item1;
_item2 = item2;
}
public T1 GetItem(T1 _) => _item1;
public T2 GetItem(T2 _) => _item2;
private T GetItem<T>(T x)
{
throw new ArgumentException();
// return x;
}
public T Get<T>()
{
return GetItem(default(T));
}
}
我想这样使用这个类:
var obj = new MyClass<int, string>(1, "hello");
var a = obj.Get<int>();
var b = obj.Get<string>();
但是如果我尝试这个,Generic T GetItem<T>(T x) 总是被调用(抛出异常),而不是非泛型实现。
如果我尝试直接访问GetItem 方法,它会按预期工作:
var obj = new MyClass<int, string>(1, "hello");
var q = obj.GetItem(default(int));
var w = obj.GetItem(default(string));
q 和 w 按预期包含 1 和 hello。
有没有办法让我随心所欲地使用这个类(使用obj.Get<T>)?我想避免Item1 Item2 Item3 getters。
【问题讨论】:
-
您能否说明您是如何尝试使用该帖子中的答案的?
-
你的代码有很大缺陷。您有两个相同的方法
GetItem,它们根据唯一目的是区分调用的参数返回不同的东西。您应该为此使用两个不同的名称,例如GetItem1和GetItem2. -
重载解析是在编译时完成的,而不是在运行时。当编译器编译
Get<T>方法时,它必须立即决定要调用GetItem的哪个重载。当然,此时编译器不知道T将是什么:它可能是string或int或其他任何东西。所以它必须选择通用的GetItem<T>重载 -
当你想要一个包含两个相同类型项目的元组时,你将陷入痛苦的世界......
-
@Sweeper 如果我将动态与泛型一起使用,那么我总是必须将数据参数作为参数传递(我的第二个示例),或者调用泛型 T (我的第一个示例)。如果我不使用泛型,那么......好吧,我不能使用违背目的的泛型。在这种情况下,
dynamic没有任何效果。 @Matthew 具有相同类型的两个项目破坏了业务规则。在这种情况下,UB 是可以接受的。