[英]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
的參數。 然后,我們測試實際傳遞的參數,以查看它是此類應專門處理的東西,還是基類的方法應處理的東西。
請注意,如果需要,您甚至可以將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 );
}
}
}
您需要使用一個記錄界面。 讓我們在此接口中添加一個方法,以便稍后可以看到它。
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.