[英]Overload resolution, extension methods and genericity in C#
我在C#源代码中有以下场景:
class A{}
class Dispatch<T>{}
static class DispatchExt
{
public static void D<T>(this Dispatch<T> d, int a)
{
Console.WriteLine("Generic D chosen with a = " + a.ToString());
}
public static void D(this Dispatch<A> d, int a)
{
Console.WriteLine("D<A> chosen with a = " + a.ToString());
}
}
class Program
{
static void D<T>(Dispatch<T> d, int a)
{
d.D(a);
}
static void Main(string[] args)
{
int a = 5;
var dispatch = new Dispatch<A>();
dispatch.D(a);
D(dispatch, a);
}
}
当我运行此代码时输出为:
“ D<A>
选择a = 5”
“选择a = 5的通用D
”
这个结果让我感到惊讶,因为在这两种情况下,我都期待“ D<A>
= A”选择a = 5“。
我想知道在这种情况下什么是一般的重载解析规则,或任何导致此输出的东西。 此外,我想知道是否有办法在两种情况下实现第一次输出。
扩展方法是语法糖,在编译时使用仅从静态类型系统获取的信息进行解释。
举个例子,你有这个:
dispatch.D(a);
dispatch
的类型为Dispatch<A>
,其中存在扩展方法。 因此编译器将其转换为DispatchExt.D(dispatch, a)
(非泛型版本)。
在你的第二个例子中,你有这个:
d.D(a);
d
的类型为Dispatch<T>
。 所以这采用了泛型扩展方法DispatchExt.D<T>(d, a)
。
由于转换发生在编译时,因此不考虑实际的运行时类型。
这是顺便说一句。 在其他情况下确定重载时使用的相同行为:仅考虑静态编译时类型:
A a = new A();
B b = new B();
A ba = b;
Test(a); // "a"
Test(b); // "b"
Test(ba); // "a"
使用以下定义:
public void Test(A a) { Console.WriteLine("a"); }
public void Test(B a) { Console.WriteLine("b"); }
public class A {}
public class B : A {}
我认为你的意思是这样的 - 一种自称的链式方法。 我做了一个数字总和的多次调用。
using System;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var magic = new Magic();
var sum = magic.MagicAdd(2).MagicAdd(20).MagicAdd(50).MagicAdd(20).Result;
Console.WriteLine(sum);
Console.ReadKey();
}
}
public class Magic
{
public int Result { get; set; }
//method chaining
public Magic MagicAdd(int num)
{
this.Sum(num);
return this;
}
public int Sum(int x)
{
this.Result = this.Result + x;
return this.Result;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.