[英]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.