繁体   English   中英

在基本方法中使用派生类

[英]Using Derived Class In a Base Method

我想尽可能地重用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
    }
}

注意,当BaseRecordProcessor类中的虚拟方法传递给BaseRecord类时, DerivedRecordProcessor类中的DoStuff方法将向该方法传递DerivedRecordOne类。 有没有办法做到这一点?

以下是记录类:

public class BaseRecord
{
    // hold record information
}

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

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

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

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

public class DerivedRecordProcessor : BaseRecordProcessor<DerivedRecordOne>
{
    public override void DoStuff(DerivedRecordOne derived)
    {
    }
}

编辑:刮开原始示例,我没有足够好地阅读问题。 相同的想法可行,但是我更新了示例以匹配您的实际操作。

您可以在方法中将接口添加为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
    }
}

对您发布的代码进行少量更改:

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的参数。 然后,我们测试实际传递的参数,以查看它是此类应专门处理的东西,还是基类的方法应处理的东西。

请注意,如果需要,您甚至可以将recordDerivedRecordProcessor ,并将其用于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 );
        }
    }
}

您需要使用一个记录界面。 让我们在此接口中添加一个方法,以便稍后可以看到它。

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

暂无
暂无

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

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