简体   繁体   English

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

[英]Passing Classes with same interface or base class to overloaded methods

I have a base class with has x amount of properties, I then have derived classes with more properties. 我有一个具有x个数量的属性的基类,然后有了具有更多属性的派生类。 How do I process the common fields in a method and then send the object to another method which can process its additional properties? 如何处理方法中的公共字段,然后将对象发送到可以处理其附加属性的另一个方法?

Example: 例:

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
}

It sounds like you basically want overload resolution at execution time. 听起来您基本上是想在执行时进行重载解析。 (I'm assuming you can't introduce a virtual method to do the right thing, and implement it in each class. That would be the cleanest way if it's reasonable for the implementations to know what you're doing with them, but that's not always the case.) The simplest way of achieving that is using dynamic , as introduced in C# 4: (我假设您不能引入虚拟方法来做正确的事情,并在每个类中实现它。如果实现知道您对它们的操作是合理的,那将是最干净的方法,但这就是并非总是如此。)最简单的实现方法是使用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
}

The best way without getting into advanced strategies is to use the is keyword. 不采用高级策略的最佳方法是使用is关键字。

For example: 例如:

Method1(IAnimal a) {
    // process NoOfFeet

    if (a is Elephant)
        DoSomething((Elephant)a);
    else if (a is Dog)
        DoSomething((Dog)a);
}

If Elephant and Dog , etc. might have additional subclasses that you need to specifically address, then you will need to use typeof instead of is : 如果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);
}

Make the method a part of the class and override it. 使方法成为类的一部分并覆盖它。

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();
}

Sounds like you could use the Template method pattern 听起来您可以使用Template方法模式

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
    }
}

Now when you call DoSomething() on any animal object, the base class will handle the common functionality, then pass down execution to the derived class to for 现在,当您在任何动物对象上调用DoSomething()时,基类将处理通用功能,然后将执行传递给派生类以用于

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM