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