将具有相同接口或基类的类传递给重载方法
本文关键字:方法 重载 基类 接口 | 更新日期: 2023-09-27 17:56:58
我有一个基类,具有x数量的属性,然后我具有更多属性的派生类。如何处理方法中的公共字段,然后将对象发送到另一个可以处理其附加属性的方法?
例:
public Interface IAnimal {
int NoOfFeet;
}
class Animal: IAnimal {
int NoOfFeet {get;set;}
}
class Elephant: Animal {
bool hasTrunk {get;set;}
}
class Dog:Animal {
string canBark {get;set;}
}
Method1(IAnimal a) {
//process NoOfFeet ...
//process fields for derived type
DoSomething(IAnimal a)
}
DoSomething(Elephant e) {
//process trunk
}
DoSomething(Dog d) {
//process canbark
}
听起来您基本上希望在执行时解决重载问题。(我假设你不能引入一个虚拟方法来做正确的事情,并在每个类中实现它。如果实现知道你用它们做什么是合理的,那将是最干净的方法,但情况并非总是如此。实现此目的的最简单方法是使用 dynamic
,如 C# 4 中所述:
public void Method(IAnimal animal)
{
// We don't want to call Handle with a null reference,
// or we'd get an exception to due overload ambiguity
if (animal == null)
{
throw new ArgumentNullException("animal");
}
// Do things with just the IAnimal properties
Handle((dynamic) animal);
}
private void Handle(Dog dog)
{
...
}
private void Handle(Elephant elephant)
{
...
}
private void Handle(object fallback)
{
// This method will be called if none of the other overloads
// is applicable, e.g. if a "new" implementation is provided
}
使该方法成为类的一部分并重写它。
public Interface IAnimal {
int NoOfFeet;
void DoSomething()
}
Class Animal: IAnimal {
int NoOfFeet {get;set;}
public virtual void DoSomething() {...}
}
Class Elephant: Animal {
bool hasTrunk {get;set;}
public override void DoSomething() {...}
}
Class Dog:Animal {
string canBark {get;set;}
public override void DoSomething() {...}
}
Method1(IAnimal a) {
//process NoOfFeet ...
//process fields for derived type
a.DoSomething();
}
不进入高级策略的最佳方法是使用 is
关键字。
例如:
Method1(IAnimal a) {
// process NoOfFeet
if (a is Elephant)
DoSomething((Elephant)a);
else if (a is Dog)
DoSomething((Dog)a);
}
如果 Elephant
和 Dog
等可能有您需要专门解决的其他子类,那么您需要使用 typeof
而不是 is
:
Method1(IAnimal a) {
// process NoOfFeet
if (a.GetType() == typeof(Elephant))
DoSomething((Elephant)a);
else if (a.GetType() == typeof(Dog))
DoSomething((Dog)a);
}
听起来你可以
使用模板方法模式
abstract class Animal
{
public void DoSomething()
{
// do stuff all animals have here
DoSomethingVirtual(); // call virtual method to do stuff for specific animal
}
private abstract void DoSomethingVirtual();
}
class Elephant : Animal
{
private override void DoSomethingVirtual()
{
// do elephant stuff here
}
}
现在,当您在任何动物对象上调用DoSomething()
时,基类将处理公共功能,然后将执行传递给派生类 for