在基本方法中使用派生类

时间:2014-10-10 21:38:05

标签: c# .net inheritance

我想尽可能多地重用BaseRecordProcessor类中的代码,但是我无法弄清楚如何在基类中使用派生类。

我想要做的一个例子如下。

public class BaseRecordProcessor
{
    public void ProcessRecord()
    {
        List<BaseRecord> records = GetRecordValues();

        foreach (BaseRecord record in records)
        {
            DoStuff(record);
        }
    }

    public virtual DoStuff (BaseRecord record)
    {
        // do stuff
    }
}

public class DerivedRecordProcessor : BaseRecordProcessor
{
    public override DoStuff (DerivedRecordOne record)
    {
        // do stuff
    }
}

注意DoStuff类中的DerivedRecordProcessor方法将DerivedRecordOne类传递给方法,而BaseRecordProcessor类中的虚方法正在传递BaseRecord类1}}类。有没有办法做到这一点?

以下是记录类:

public class BaseRecord
{
    // hold record information
}

public class DerivedRecordOne : BaseRecord
{
    // hold additional record information
}

public class DerivedRecordTwo : BaseRecord
{
    // hold more record information
}

4 个答案:

答案 0 :(得分:2)

您可以使用泛型来完成此操作。像这样:

public class BaseRecordProcessor<T> where T : BaseRecord
{
    public virtual void DoStuff(T myObj)
    {
    }
}

public class DerivedRecordProcessor : BaseRecordProcessor<DerivedRecordOne>
{
    public override void DoStuff(DerivedRecordOne derived)
    {
    }
}
编辑:抓住原来的例子,我没有充分阅读这个问题。同样的想法是有效的,但我更新了示例以匹配您实际执行的操作。

答案 1 :(得分:0)

您可以将接口添加为IRecord,并在方法中添加IRocord作为参数,如

public Interface IRecord
{
    ...
}
public class BaseRecord:IRecord
{
    //hold record information
}

public class DerivedRecordOne : BaseRecord,IRecord
{
    //hold additional record information
}

public class BaseRecordProcessor
{

    public virtual DoStuff(IRecord record)
    {
        //do stuff
    }
}
public class DerivedRecordProcessor : BaseRecordProcessor
{
    public override DoStuff(IRecord record)
    {
        //do stuff
    }
}

答案 2 :(得分:0)

对您发布的代码进行细微更改:

public class DerivedRecordProcessor : BaseRecordProcessor
{
    public override DoStuff (BaseRecord record)
    {
        if( record is DerivedRecordOne ) 
        {
            // Do DerivedRecordOne stuff here
        } 
        else 
        {
           // do base stuff
           base.DoStuff( record );
        }
    }
}

这是多态,并且使用C#的对象类型检测对您有利。为此,我们将DerivedRecordProcessor.DoStuff()更改为参数BaseRecord。然后我们测试实际传递的参数,看它是否是这个类应该专门处理的东西,或者它是否是基类的方法应该处理的东西。

注意,如果需要,您甚至可以将record投射到DerivedRecordProcessor,并将其用于if测试(因此您不必在以后进行投射)。这给了我们:

public class DerivedRecordProcessor : BaseRecordProcessor
{
    public override DoStuff (BaseRecord record)
    {
        DerivedRecordOne derivedRecordOne = record as DerivedRecordOne;
        if( null != derivedRecordOne ) 
        {
            // Do DerivedRecordOne stuff here using local variable derivedRecordOne 
        } 
        else 
        {
           // do base stuff
           base.DoStuff( record );
        }
    }
}

答案 3 :(得分:0)

您需要使用记录界面。让我们为这个界面添加一个方法,以便我们以后可以看到它。

public interface IRecord
{
    void DisplayName();
}

请注意,所有您的记录类型需要实现此接口。

public class BaseRecord : IRecord
{
    public void DisplayName()
    {
        Console.WriteLine("BaseRecord");
    }
}

public class DerivedRecordOne : BaseRecord, IRecord
{
    public void DisplayName()
    {
        Console.WriteLine("DerivedRecordOne");
    }
}

public class DerivedRecordTwo : BaseRecord, IRecord
{
    public void DisplayName()
    {
        Console.WriteLine("DerivedRecordTwo");
    }
}

我们现在可以调整处理类型以获取接口,而不是特定类型。

public class BaseRecordProcessor
{
    public void ProcessRecords()
    {
        foreach (var record in GetRecordValues())
        {
            DoStuff(record);
        }
    }

    public virtual void DoStuff(IRecord record)
    {
        // do stuff
    }

    private List<IRecord> GetRecordValues()
    {
        var records = new List<IRecord>();

        records.Add(new BaseRecord());
        records.Add(new DerivedRecordOne());
        records.Add(new DerivedRecordTwo());

        return records;
    }
}

public class DerivedRecordProcessor : BaseRecordProcessor
{
    public override void DoStuff(IRecord record)
    {
        record.DisplayName();
    }
}

如果您现在实例化一个记录处理器,并运行它:

DerivedRecordProcessor processor = new DerivedRecordProcessor();
processor.ProcessRecords();

您将看到预期的结果:

  

BaseRecord

     

DerivedRecordOne

     

DerivedRecordTwo

我会留给您调查每个记录类型需要实现的原因IRecord:P