Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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# 为什么在基类构造函数中设置时,重写的get only属性保持null?_C#_Automatic Properties - Fatal编程技术网

C# 为什么在基类构造函数中设置时,重写的get only属性保持null?

C# 为什么在基类构造函数中设置时,重写的get only属性保持null?,c#,automatic-properties,C#,Automatic Properties,我尝试了以下示例: public class TestBase { public virtual string ReadOnly { get; } public TestBase() { ReadOnly = "from base"; } } class Test : TestBase { public override string ReadOnly { get; } public Test() { /

我尝试了以下示例:

public class TestBase
{
    public virtual string ReadOnly { get; }

    public TestBase()
    {
        ReadOnly = "from base";
    }
}

class Test : TestBase
{
    public override string ReadOnly { get; }
    public Test()
    {
        // nothing here
    }
}
当我创建一个Test实例时,我看到ReadOnly保持为null。但是为什么呢?
我真的不懂,谁能给我解释一下为什么会这样?至少我希望有一个错误,即只读属性不能设置在拥有的类之外。

< P>最简单的解释方法是考虑编译器生成的代码来实现这个。 基类与此等效:

public class TestBase
{
    public virtual string ReadOnly => _testBaseReadOnly;

    public TestBase()
    {
        _testBaseReadOnly = "from base";
    }

    readonly string _testBaseReadOnly;
}
class Test : TestBase
{
    public override string ReadOnly => _testReadOnly;

    readonly string _testReadOnly;
}
派生类与此等效:

public class TestBase
{
    public virtual string ReadOnly => _testBaseReadOnly;

    public TestBase()
    {
        _testBaseReadOnly = "from base";
    }

    readonly string _testBaseReadOnly;
}
class Test : TestBase
{
    public override string ReadOnly => _testReadOnly;

    readonly string _testReadOnly;
}
这里需要注意的重要一点是,派生类有自己的支持字段,用于
ReadOnly
——它不会重复使用基类中的支持字段

意识到这一点后,应该很清楚为什么重写的属性为null

这是因为派生类有自己的
ReadOnly
支持字段,并且它的构造函数没有初始化该支持字段

顺便说一句,如果您使用的是
Resharper
,它实际上会警告您没有在派生类中设置
ReadOnly

 "Get-only auto-property 'ReadOnly' is never assigned."

编译器将其处理如下;基本上,构造函数中的代码写入原始备份字段,位于
TestBase
。似乎您的场景不受支持,但是。。。我不知道语言小组是否考虑过这件事

顺便说一句:如果你想看看编译器对代码做了什么:

公共类测试库
{
[编译生成]
私有只读字符串k__BackingField;//注意:在“real”C中不合法#
公共虚拟字符串只读
{
[编译生成]
得到
{
返回k__BackingField;//TestBase中的那个
}
}
公共测试库()
{
k_uubackingfield=“自基”;
}
}
内部类测试:TestBase
{
[编译生成]
私有只读字符串k__BackingField;
公共重写字符串只读
{
[编译生成]
得到
{
返回k_ubackingfield;//测试中的那个
}
}
}

@SeM这不是一个真正的重复,因为这个问题是关于重写字符串属性的影响的。@MatthewWatson你说的是第一个还是第二个?@SeM两者都有,因为这两个答案都没有提到重写属性。我想这和构造函数中的虚拟成员访问有关,不是吗?不过,如果你看看它是如何编译的,这一点很清楚:两个类都有自己的私有支持字段。返回子类中的一个。对于奖励积分,添加
Console.WriteLine(只读)Console.WriteLine(只读)ReadOnly
后,您将看到不同的症状,它将调用我们知道尚未分配的属性的后代getter,并因此尝试打印
null
。这里唯一合理的修复方法是编译子类时应该警告您实际上有两个不同的属性实现。