派生 class 是否可以在 C# 中保存对现有基础 class 的引用?

Is it possible for a derived class to hold a reference to an existing base class in C#?

假设下面的代码。是否可以使用现有基础 class 的实例创建派生 class?还是使用扩展方法是这里的最佳解决方案?

public class TestThis
{
    public void Test1()
    {
        A a = GetAFromExternalSystem();

        B b = new B(a);

        a.Value = 5;

        b.Value == 5; //want this line to return true.  In other words, b to hold a reference to a.
    }

    private A GetAFromExternalSystem()
    {
        return new A();
    }
}

public class A
{
    public string Name { get; set; }
    public int Value { get; set; }
}

public class B : A
{
    public B(A a)
    {
        this = a;  //Cannot assign to 'this' because it is read-only
    }
    public int Ranking { get; set; }
}

不,你不能这样做。

创建派生 class 时,基础 class 也被创建 并且是派生 class 的 "part" ].您不能简单地将派生 class 的基数部分重新分配给其他东西。

虽然修复非常简单,只需复制您关心的成员即可。

您通常会这样做:

public class A
{
    public A(string name, int value) 
    {
      this.Name = name;
      this.Value = value;
    }
    public string Name { get; set; }
    public int Value { get; set; }
}

public class B : A
{
    public B(A a) : this(a.Name, a.Value, 0)
    {
    }
    public B(string name, int value, int ranking) : base(name, value)
    {
      this.Ranking = ranking;
    }
    public int Ranking { get; set; }
}

仔细研究并确保您了解其工作原理。如果您对它的工作原理有疑问,post 一个新的、精确的、明确的问题。

现在,这没有你想要的 属性,即更新 A 也更新 B。做那件奇怪的事情的方法是放弃 B 之间的 is-a-kind-of 关系和答:

public class B
{
    private A a;
    public B(A a)
    {
      this.a = a;
    }
    public int Ranking { get; set; }
    public int Value 
    { 
      get { return this.a.Value; }
      set { this.a.Value = value; }
    }
    public string Name 
    { 
      get { return this.a.Name; } 
      set { this.a.Name = value; }
    }  
}

现在,如果您既想让 B 服从 A,又想让 B 成为 A 的实例,那么您的问题就更难了; A 的属性必须是虚拟的,并且在 B 中被覆盖。我把它留作练习。

但实际上,您似乎想在这里做一些非常奇怪的事情。您能描述一下您实际要解决的问题吗?你做错的可能性很大。

您不能使用派生的 class 执行此操作,尽管这可能是 X / Y Problem。要实现您在测试用例中想要实现的目标,可以使用包装器 class

public class TestThis
{
    public void Test1()
    {
        A a = GetAFromExternalSystem();

        B b = new B(a);

        a.Value = 5;

        b.Value == 5;
    }

    private A GetAFromExternalSystem()
    {
        return new A();
    }
}

public class A
{
    public string Name { get; set; }
    public int Value { get; set; }
}

public class B  // B acts as a 'wrapper' for A
{
    public B(A a)
    {
        this.A = a;
    }
    public A A { get; set; }
    public int Value { 
        get { return A.Value; }
    }
    public int Ranking { get; set; }
}