Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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# 如何保护基本场&x27;s公共/私人_C#_Oop_Inheritance - Fatal编程技术网

C# 如何保护基本场&x27;s公共/私人

C# 如何保护基本场&x27;s公共/私人,c#,oop,inheritance,C#,Oop,Inheritance,如果我有a类 public class ClassA { public string name; } 其中属性名是公共的,可以从任何地方修改。 我有一个B班 public class ClassB : ClassA { private string name;//But it's not Woking ,name is still public } …它继承的是ClassA,但我需要在ClassB将name作为私

如果我有a类

    public class ClassA
    {
        public string name;
    }
其中属性名是公共的,可以从任何地方修改。 我有一个B班

    public class ClassB : ClassA
    {
        private string name;//But it's not Woking ,name is still public
    }
…它继承的是ClassA,但我需要在ClassB将
name
作为私有字段。
因此,如果我创建类型为ClassB的对象,则
ClassB.name
无法修改。

这是不可能的。不能更改基类字段的可见性。

只需不发布字段,而是发布访问器:

public class ClassA
{
    private string _name;
    public string Name { get { return _name; } protected set { _name = value; } }
}

public class ClassB : ClassA
{
  /* nothing left to do - you can set Name in here but not from outside */
}

假设您无法更改,请不要使用继承,而是使用聚合和委派:

public class A {
  public string name;
  public int f() { return 42; }
}

public class B {
  private A a;
  public int f() { return a.f(); }
  public string getName() { return a.name; }
}

如果您无法控制ClassA,可以执行以下操作:

void Main()
{   
    var b = new ClassB();
    var a = (ClassA)b;
    a.name = "hello";
    b.PrintName();
}

class ClassA {
    public string name;
}

class ClassB : ClassA  {
    private new string name;
    public void PrintName() {
        Console.WriteLine(base.name);
    }
}

卡斯滕·科尼格(Carsten Konig)的方法是一种很好的方法,这里有另一种选择

public class ClassA {
    public virtual string Name {
        get;
        private set;
    }
}

public class ClassB : ClassA {
    public override string Name {
        get {
            return base.Name;
        }
    }
}

嗯,这有两个诀窍。但它们都不是你真正想要的。一是:

    public class ClassA 
    {
        protected string name;
        public string Name { get { return name; } public set { name = value; } }
    }

public class ClassB : ClassA
    {
         public new string Name { get { return base.name; } }
    }

是否确实要有两个同名字段?声明名称在ClassA中受保护,这样只有ClassA和ClassB才能访问它,这样做不会有帮助吗?@Davide Piras是的,我确定,因为ClassA.name应该是可见的,并且没有经过验证,但是在ClassB.name是我关心的问题,我应该将其私有化。不要将字段公开-糟糕的设计如果你不想修改
ClassB.name
,请将其设置为
readonly
(你需要使用属性而不是字段)@Carsten并非所有的公共字段都是糟糕的设计。公共只读字段是最适合不可变DTO的字段。但在ClassA中,名称并不是真正的“公共”-您不能在ClassA和ClassB之外更改它的值:(@Prator12,您也不应该这样做。如果您在类A中更改名称,则可以执行类似
((ClassA)objectB)的操作。Name=“并且它是可设置的”
这不仅仅是一个打印问题,这里的解决方案是
new
关键字。它隐藏了以前的公共字段。