字符串未分配?

时间:2015-04-16 05:21:24

标签: c# variables inheritance variable-assignment

using System;

public class Shurli
{
    public class MyTest
    {
        private string name = "qwe";   // the name field
        public string Name   // the Name property
        {
            get
            {
                return this.name;
            }
        }
    }

    public class yourJs : MyTest
    {
        private string name = "chah";
    }

    static void Main()
    {
        var met = new yourJs();

        string acer = met.Name;
        Console.WriteLine(acer);
    }
}

我完全希望输出为" chah",但输出是" qwe"。我几个小时前一直试图弄清楚这一点,但仍然无法解决这个问题。有人可以帮忙吗?

Visual Studio发出警告:"字段' Shurli.yourJs.name'已分配但其值永远不会被使用"

4 个答案:

答案 0 :(得分:4)

nameMyTest类中的yourJs字段位于两个不同的范围内 - 即使它们具有相同的名称,它们也完全相互独立。

为了使代码按照您描述的方式工作,name应仅在基类中声明为protected字段,然后在子类中指定。

public class MyTest
{
    protected string name = "qwe";   // the name field
    public string Name   // the Name property
    {
        get
        {
            return this.name;
        }
    }
}

public class yourJs : MyTest
{
    public yourJs()
    {
        name = "chah";
    }
}

答案 1 :(得分:0)

met.Name将引用MyTest中的继承属性Name,因为yourJs仅包含name,它是私有成员,并且不能是类外的访问定向形式。请记住,C#区分大小写,nameName是两个不同的变量。

如果要访问yourJs名称私有数据成员,则需要将其公开或将其值访问某些公共方法/属性。

要检查您是否可以访问name中的会员yourJs,我们会将其公开。

public class yourJs : MyTest
{
    public string name = "chah";
}

static void Main()
{
    var met = new yourJs();

    string acer = met.name;
    Console.WriteLine(acer);
}

编辑根据评论,了解私人会员与公共财产之间的关系。

Properties

  

属性是一个提供灵活读取机制的成员,   写或计算私有字段的值。可以使用属性   好像他们是公共数据成员,但他们实际上是特殊的   称为访问器的方法。这样可以轻松访问数据   仍然有助于提高方法的安全性和灵活性。

答案 2 :(得分:0)

private string name = "chah";会在班级yourJs中声明字段。
因此,您有两个字段name - 一个在MyTest中,一个在yourJs上。

AND:属性Name返回字段MyTest.name,因为Name中声明了MyTest

这与private修饰符无关 - 问题是引入了第二个name字段。

如果您想更改nameyourJs的值,则必须声明它不同:

public class MyTest {
    protected string name = "qwe";   // This is the ONLY name field, visible by inherited classes

    public string Name {
        get { return this.name; }
    }
}

public class yourJs: MyTest {
    public yourJs() {
        name = "chah";              // Change the value of MyTest.name
        base.name = "chah";         // Same as above, but explicit useage of base class MyTest
    }
}

答案 3 :(得分:0)

在内存中,yourJs对象将具有一个Name属性和两个名为name的实例字段(一个继承自其基类 MyTest派生类本身声明的一个)。

  • 在派生类型中声明的字段name隐藏继承的字段。
  • 继承的属性Name始终引用继承的字段 name,无论您使用哪些访问修饰符用于字段。

您有三种方法可以获得所需的输出:

选项1 :正如BJ Myers所述,name字段只应在基类中声明,然后在派生类中指定。

选项2 :在派生类中声明一个具有相同名称的新属性(隐藏继承的属性)。

public class MyTest
{
    private string name = "qwe";
    public string Name { get { return name; } }
}

public class yourJs : MyTest
{
    private string name = "chah";
    public new string Name { get { return name; } }
}

选项3 :重写继承的属性以使用派生类中声明的字段。

public class MyTest
{
    private string name = "qwe";
    public virtual string Name { get { return name; } }
}

public class yourJs : MyTest
{
    private string name = "chah";
    public override string Name { get { return name; } }
}