关于C#:在构造函数中初始化虚拟属性是错误的吗?

Is it wrong to initialize a virtual Property in the constructor?

本问题已经有最佳答案,请猛点这里访问。

在构造函数中初始化虚拟属性是否错误?它只是感觉不正确,因为如果重写派生类中的属性,则该属性将首先用基类构造函数中的值初始化,然后由派生类构造函数再次分配。有没有其他办法来做这个?我在说这样的事

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
internal class B1
{
    public B1()
    {
        Ti ="Hello";
    }

    public virtual string Ti { get; set; }
}

internal class B2 : B1
{
    public B2()
    {
        Ti ="HelloKitty";
    }

    public override string Ti { get; set; } //<--"Hello" will be assigned first then"HelloKitty" will be assigned
}

internal class Program
{
    private static void Main(string[] args)
    {
        var b2 = new B2();
        Console.WriteLine(b2.Ti);
        Process.GetCurrentProcess().WaitForExit();
    }
}

更新1:按照@ak的建议_

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
internal class Bb1
{
    private string _ti;

    public Bb1()
    {
        _ti ="Hello";
    }

    public virtual string Ti
    {
        get { return _ti; }
        set { _ti = value; }
    }
}

internal sealed class Bb2 : Bb1
{
    public Bb2()
    {
        Ti ="HelloKitty";
    }

    public override string Ti { get; set; }
}

基类中的变量"ti"由"hello"初始化。_ti is still in the base class

如果我使用的不是字符串类型,而是显式需要公开的类型,该怎么办?


另一方面,这是合理的(请注意,B2已密封)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
internal class B1
{
    private string m_ti;
    public virtual string Ti { get{return m_ti;} set{m_ti = value;} }
    public B1()
    {
        m_ti ="Hello";
    }


}

internal sealed class B2 : B1
{
    public B2()
    {
        Ti ="HelloKitty";
    }

    public override string Ti { get; set; } //<--"Hello" will be assigned first then"HelloKitty" will be assigned
}

另一个选项受保护的构造函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
internal class B1
{
    private string m_ti;
    public virtual string Ti { get { return m_ti; } set { m_ti = value; } }
    public B1()
    {
        m_ti ="Hello";
    }

    protected B1(String word)
    {
        m_ti = word;
    }
}

internal sealed class B2 : B1
{
    public B2():base("kitty")
    {

    }
}