我有基类和两个继承的类,这两个继承的类也共享两个属性。我想从基类访问这些属性。怎么做?以下示例。
public abstract class ClientEngine
{
public void SaveFile(string fileName);
{
//Not implemented, I get error here because I don't know how to access Inherited class properties
if (FileStorage != null))
File.WriteAllBytes(fileName, FileStorage);
}
}
public interface IEngineEntity
{
byte[] FileStorage { get; set; }
}
public class MyEntity1 : ClientEngine, IEngineEntity
{
public string MyProperty1 {get; set;}
public string MyProperty2 {get; set;}
public byte[] FileStorage { get; set; }
}
public class MyEntity2 : ClientEngine, IEngineEntity
{
public string MyProperty3 {get; set;}
public string MyProperty4 {get; set;}
public byte[] FileStorage { get; set; }
}
答案 0 :(得分:4)
如果您需要从基类访问属性,那么您做错了。请记住未来的设计。
您应该在基类中声明FileStorage
,因为两个继承的类都有它。
如果您不想定义FileStorage
的特定类型(例如byte[]
),则可能需要将其定义为更通用的类型,例如IEnumerable<byte>
。或者,您可以将FileStorage
声明为提供从基类访问所需的任何行为的接口。
<强>更新强>
@ghimireniraj的一个很好的观察:你还应该尝试从IEngineEntity派生ClientEngine。面向对象设计的一个底线是,如果您在所有继承的类中复制行为,它应该在基类中。
但是,你真的想从基类访问一些代码吗?你不应该。但如果你真的需要,你总是可以施展:
public abstract class ClientEngine
{
public void SaveFile(string fileName);
{
byte[] fileStorage = null;
if (this is MyEntity1)
{
MyEntity1 me1 = (MyEntity1)this;
fileStorage = me1.FileStorage;
}
else if (this is MyEntity2)
{
MyEntity2 me2 = (MyEntity2)this;
fileStorage = me2.FileStorage;
}
if (fileStorage != null))
File.WriteAllBytes(fileName, fileStorage);
}
}
讨厌对吗?但它应该看起来很脏,因为我们试图打破OO设计。
<强>更新强>
另一种方式是Marc Gravell提出的建议。而不是强制转换为类型,转换为接口。但所有这些对我来说仍然闻起来很糟糕:我坚信你可以改善你的设计。答案 1 :(得分:3)
这样做的方法是使它成为基类中的抽象成员,并在派生中重写;您可以使用的另一种方法是尝试将this
转换为IEngineEntity
- 如果成功,则通过界面使用它,即
var engine = this as IEngineEntity;
if(engine == null) throw new InvalidOperationException(
"All engine implementations must provide an IEngineEntity implementation");
var bytes = engine.FileStorage;
它似乎有点异常,但如果它是所有子类的授权,不要把它推到基类。通过将其推送到基类,您无法忘记实现缺少的成员。
答案 2 :(得分:0)
另一种功能替代方案:
var derivedType = Type.GetType(this.GetType().FullName);
var FileStorage = derivedType.GetProperty("FileStorage", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic).GetValue(this) as byte[];
if (FileStorage != null)
{
...
}