gpt4 book ai didi

c# 泛型和非泛型方法之间的重载解析

转载 作者:太空狗 更新时间:2023-10-29 22:51:53 24 4
gpt4 key购买 nike

我在 Internet 和 stackoverflow 上进行了一些基本搜索,当涉及通用版本方法和非通用版本方法时,我看到了很多关于重载解析的讨论。我知道重载解析是在编译时完成的——因此如果我有这段代码:

public class A<T>
{
public void DoStuff(T value)
{
InternalDoStuff(value);
}

protected void InternalDoStuff(int value)
{
Console.WriteLine("Non-generic version");
}

protected void InternalDoStuff(T value)
{
Console.WriteLine("Generic version");
}

}

public class Test
{
static void Main (string [] args)
{
A<int> a = new A<int> ();
a.DoStuff(100);
}
}

输出将是“Generic version”,因为“InternalDoStuff”的解析已经被编译器整理出来,编译器看到的是“InternalDoStuff is called with a T type parameter in DoStuff”。

但是我不知道这是否会有所不同:

public class B : A <int> 
{

}

public class Test
{
static void Main (string [] args)
{
B b = new B ();
b.DoStuff(100);
}
}

现在我可以说编译器有足够的信息来决定“B 是 A 的特定版本”,因此调用非通用版本的 InternalDoStuff 吗?

有什么通用的原则可以分析这种重载决议吗?

最佳答案

第二种方法与第一种方法在任何意义上都没有什么不同。

从 A 派生类 B 绝不会更改为类 A 生成的 IL 代码。B 只是继承了这些方法。

如果查看类 A 的 IL 代码,您会发现它编译为调用通用版本而不是非通用版本 -

.method public hidebysig instance void DoStuff(!T 'value') cil managed
{
.maxstack 8
L_0000: nop
L_0001: ldarg.0
L_0002: ldarg.1
L_0003: call instance void
ConsoleApplication1.A`1<!T>::InternalDoStuff(!0) <-- Generic version
L_0008: nop
L_0009: ret
}

来自 Jon Skeet 的文章 here -

Just as a reminder, overloading is what happens when you have two methods with the same name but different signatures. At compile time, the compiler works out which one it's going to call, based on the compile time types of the arguments and the target of the method call. (I'm assuming you're not using dynamic here, which complicates things somewhat.)

正如他提到的,使用动态延迟解析直到运行时。这段代码将为您的两种方法调用非通用版本方法 -

public void DoStuff(T value)
{
dynamic dynamicValue = value;
InternalDoStuff(dynamicValue);
}

通过Jon Skeet引用这里的答案和 Eric Lippert详细描述。

关于c# 泛型和非泛型方法之间的重载解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18339503/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com