将值设置为派生类中的字段

时间:2009-08-21 05:06:38

标签: c# inheritance

using System;

namespace ConsoleApplication1
{ 
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(new B("MyName").Name);
        }
    }

    abstract class A
    {
        public A(string name)
        {
            this.GetType().GetField("Name").SetValue(this, name);
        }
    }

    class B : A
    {
        public B(string name)
            : base(name)
        {
        }

        public string Name
        {
            set;
            get;
        }
    }
}

是否可以做类似的事情?

5 个答案:

答案 0 :(得分:4)

我无法强调这是多么非常非常糟糕。您正在创建一个复杂的,令人困惑和做作的逆耦合,严重缺乏清晰度,失败的最佳实践和面向对象的主体,这将为实现抽象类派生的人们创建维护和管理的噩梦。做正确的事!!

abstract class A
{
    protected A(string name)
    {
        Name = name;
    }

    public abstract string Name
    {
        get;
        protected set;
    }
}

class B: A
{
    public B(string name) : base(name)
    {
    }

    private string m_name;

    public override string Name
    {
        get { return "B Name: " + m_name; }
        protected set
        {
           m_name = value;
        }
    }
}

答案 1 :(得分:1)

有可能,但我不建议这样做。问题是你的基类知道很多关于从它派生的类。

从抽象基类派生一个未定义属性 Name 的类时,运行时会出现异常。

如果您希望从您的基类派生的每个类都具有属性 Name ,那么在您的摘要中定义Property Name 会更容易基类,并使用构造函数设置属性。

答案 2 :(得分:1)

这样做非常糟糕。通常,您应该调用类似'SetPossibleData()'的方法,并强制所有孩子以他们决定的方式实现它。

为什么需要这样做?

答案 3 :(得分:0)

使用GetProperty()方法,

public A(string name) 
    {
        this.GetType().GetProperty("Name").SetValue(this,name,null);
    }

答案 4 :(得分:0)

如果每个类初始化它定义的字段和属性,那将非常简单。为什么B期望基类初始化其名称?

abstract class A
{
    public A()
    {
    }
}

class B : A
{
    // I know, its trivial, but it does the same ...
    public B(string name) : base()
    {
        Name = name;
    }

    public string Name { set; get; }
}

我唯一能想到你编写这段代码的原因是基类有一些初始化字段的逻辑。直接前进是让派生类调用逻辑,但初始化字段本身:

abstract class A
{
    public A()
    {
    }

    protected string GenerateName(string someArg)
    {
        // complicated logic to generate the name
    }

}

class B : A
{
    public B(string someArg) : base()
    {
        Name = base.GenerateName(someArg);
    }

    public string Name { set; get; }
}