I have base class and two inherited classes, these two inherited classes also share the two properties. I would like to access these properties from base class. How to do that? Example below.
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 : ClientE开发者_JAVA百科ngine, 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; }
}
If you need to access a property from the base class, you are doing something wrong. Keep that in mind for your future designs.
You should declare FileStorage
in the base class, since both inherited classes have it.
If you do not want to define FileStorage
's specific type (say, byte[]
), you might want to define it as a more generic type, such as IEnumerable<byte>
. Alternatively, you can declare FileStorage
as an interface who provides whatever behavior you need to access from base class.
Update
A nice observation by @ghimireniraj: you should also try to derive ClientEngine from IEngineEntity. One of the bottom lines for OO design is that if you replicate behavior in all inherited classes, it should be in the base class.
But, do you really want to access some code from base class? You shouldn't. But if you really need, you can always cast:
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);
}
}
Nasty right? But it should look dirty, because we are trying to break OO design.
Update
Another way is going by Marc Gravell's suggestion. Instead of casting to the types, cast to the interface. But all of this still smells bad to me: I firmly believe you can improve your design.
The way to do that is to make it an abstract member in the base class, and override in the derived; the other approach you could use is to try casting this
to IEngineEntity
- if it succeeds, use it via the interface, i.e.
var engine = this as IEngineEntity;
if(engine == null) throw new InvalidOperationException(
"All engine implementations must provide an IEngineEntity implementation");
var bytes = engine.FileStorage;
It does seem a little unusual, though, not to push this down to the base-class if it is a mandate of all subclasses. By pushing it to the base-class, you cannot forget to implement the missing member.
Another functional alternative:
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)
{
...
}
精彩评论