Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从基类访问继承的类属性_C#_Oop_Class_Inheritance_Base - Fatal编程技术网

C# 从基类访问继承的类属性

C# 从基类访问继承的类属性,c#,oop,class,inheritance,base,C#,Oop,Class,Inheritance,Base,我有基类和两个继承类,这两个继承类也共享这两个属性。我想从基类访问这些属性。怎么做?下面的例子 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 propertie

我有基类和两个继承类,这两个继承类也共享这两个属性。我想从基类访问这些属性。怎么做?下面的例子

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; }
}

如果需要从基类访问属性,则说明您做错了。在将来的设计中,请记住这一点

您应该在基类中声明
FileStorage
,因为两个继承类都有它

如果不想定义
文件存储
的特定类型(例如,
字节[]
),则可能需要将其定义为更通用的类型,例如
IEnumerable
。或者,您可以将
FileStorage
声明为一个接口,该接口提供您需要从基类访问的任何行为

更新

@ghimireniraj的一个很好的观察:您还应该尝试从IEngineEntity派生ClientEngine。OO设计的底线之一是,如果在所有继承的类中复制行为,那么它应该在基类中

但是,您真的想从基类访问一些代码吗?你不应该。但如果你真的需要,你可以随时施展:

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设计

更新


另一种方法是按照马克·格雷威尔的建议。转换到接口而不是转换到类型。但所有这些对我来说仍然很糟糕:我坚信您可以改进您的设计。

实现这一点的方法是使它成为基类中的抽象成员,并在派生类中重写;您可以使用的另一种方法是尝试将
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;

不过,如果这是所有子类的命令,那么不将其下推到基类似乎有点不寻常。通过将其推送到基类,您不能忘记实现缺少的成员。

另一个功能替代方案:

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) 
{
    ...
}

或者从IEngineEntity派生客户端引擎。@ghimireniraj很好。OO设计的底线之一是:如果在所有继承的类中复制行为,它应该在基类中。我不能,因为MyEntity1和MyEntity2是使用protobuf net序列化的,有理由不将文件存储放在基类中,而是将其实现为接口。我只是没有粘贴整个代码。所以回到问题上来,如何在不改变逻辑的情况下从基类访问继承类的属性。@Tomas不确定我是否看到protobuf net和这个设计决策之间的关系。如果你让我知道你想避免什么问题,我可能会建议…@downvoter请评论downvote。让我们让这个社区更有建设性。你正在寻找一个薄金属尺:请考虑你正在接受的关于你的设计的反馈,仔细考虑是否把OO的概念弯曲到你的意志上是正确的答案。1.基类中的抽象成员,以强制子类实现它;2.子类中可选重写的基类中的虚拟成员;3.当并非所有的孩子都应该有接口时,由孩子实现的接口。