簡體   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