将具有相同接口或基类的类传递给重载方法

本文关键字:方法 重载 基类 接口 | 更新日期: 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);
}

如果 ElephantDog 等可能有您需要专门解决的其他子类,那么您需要使用 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