c# java 重载操作符,C#中重载方法的一些总结

新建一个.NET Core控制台项目,我们来看看C#中重载方法的一些注意事项。

C#中多个重载方法之间的参数如果有继承关系,那么调用方法时,会调用与传入参数类型最接近的重载方法

我们来举个例子,下面我们定义了两个重载方法Do,它们的参数类型A和B是继承关系,类B继承类A,那么我们在调用Do方法时,到底调用的是哪一个重载呢?

代码如下:

using System;

namespace NetCoreOverloadParameters

{

///

/// 类A

///

class A

{

}

///

/// 类B继承类A

///

class B : A

{

}

class Program

{

///

/// 方法Do

///

/// 参数类型为A

static void Do(A a)

{

Console.WriteLine("Do A");

}

///

/// 方法Do

///

/// 参数类型为B

static void Do(B a)

{

Console.WriteLine("Do B");

}

static void Main(string[] args)

{

A a = new B();

B b = new B();

Do(a);//因为传入Do方法的类型是A,所以这里调用Do(A a)

Do(b);//因为传入Do方法的类型是B,所以这里调用Do(B a)

Do(new A());//因为传入Do方法的类型是A,所以这里调用Do(A a)

Do(new B());//因为传入Do方法的类型是B,所以这里调用Do(B a)

Do(null);//当传入null给Do方法时,这里调用的是Do(B a),说明优先调用的是继承链中参数为子类B的重载方法

Do((A)null);//因为传入Do方法的类型是A,所以这里调用Do(A a)

Console.WriteLine("Press any key to end...");

Console.ReadKey();

}

}

}

执行结果如下:

fc6dd1d36c61403b39c802e55eeb678b.png

所以我们可以看到,实际上在每次调用Do方法时,C#会选择调用和传入参数类型最接近的重载方法。

如果我们现在注释掉代码中的重载方法Do(B a),由于现在代码中只有一个Do方法了,所以所有的调用都会调用Do(A a):

using System;

namespace NetCoreOverloadParameters

{

///

/// 类A

///

class A

{

}

///

/// 类B继承类A

///

class B : A

{

}

class Program

{

///

/// 方法Do

///

/// 参数类型为A

static void Do(A a)

{

Console.WriteLine("Do A");

}

///

/// 方法Do

///

/// 参数类型为B

//static void Do(B a)

//{

// Console.WriteLine("Do B");

//}

static void Main(string[] args)

{

A a = new B();

B b = new B();

Do(a);

Do(b);

Do(new A());

Do(new B());

Do(null);

Do((A)null);

Console.WriteLine("Press any key to end...");

Console.ReadKey();

}

}

}

执行结果如下:

d5abd9e88c8fdc8eef5fa2bbe9abb209.png

C#中如果有签名相同的泛型方法和非泛型方法,那么C#会优先考虑调用非泛型方法

我们来看看下面这个例子,我们在代码中,定义了三个Do方法,其中一个非泛型方法和两个泛型方法,那么我们在调用Do方法时,C#会优先考虑调用非泛型方法:

using System;

namespace NetCoreOverloadParameters

{

///

/// 类A

///

class A

{

}

///

/// 泛型静态类Container

///

static class Container

{

///

/// 方法Do

///

/// 参数类型为A

public static void Do(A a)

{

Console.WriteLine("Do A");

}

///

/// 方法Do

///

/// 参数类型为T1

public static void Do(T1 t1)

{

Console.WriteLine("Do T1");

}

///

/// 方法Do

///

/// 类型参数T2

/// 参数类型为T2

public static void Do(T2 t2)

{

Console.WriteLine("Do T2");

}

}

class Program

{

static void Main(string[] args)

{

A a = new A();

Container.Do(a);//C#会优先考虑非泛型的方法,来匹配传入Do方法的类型,所以这里会调用重载方法Do(A a),这会导致泛型重载方法Do(T1 t1),无法被调用到

Container.Do((object)a);//将静态类Container的类型参数定义为object后,再给Do方法传入object类型的参数,这样C#就会优先调用泛型重载方法Do(T1 t1)了

Container.Do(a);//由于这里我们显式声明了类型参数,所以C#知道我们在这里要调用的是重载方法Do(T2 t2)

Console.WriteLine("Press any key to end...");

Console.ReadKey();

}

}

}

执行结果如下:

90705fd5ede450d9cff23cd09fd1bb06.png

C#中扩展方法和非扩展方法的重载

https://www.cnblogs.com/OpenCoder/category/1132736.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值