简体   繁体   中英

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

Assume the code below. Is it possible to create a derived class using an instance of the existing base class? Or is using extension methods the best solution here?

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; }
}

Here's how you would typically do this:

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; }
}

Study this carefully and make sure you understand how it works. If you have a question about how it works, post a new, precise, clear question.

Now, this does not have the property that you want, namely, that updates to A also update B. The way to do that odd thing is to abandon the is-a-kind-of relationship between B and A:

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; }
    }  
}

Now, if you want to have both B deferring to A, and also B being an instance of A, then you have a harder problem; the properties of A have to be virtual, and overridden in B. I leave that as an exercise.

But really it sounds like you are trying to do something very strange here. Can you describe the problem you're actually trying to solve? Odds are pretty good you're doing it wrong.

No, you cannot do this.

When a derived class is created, the base class is also created and is "part" of the derived class. You cannot simply reassign the base part of the derived class to something else.

The fix is pretty easy though, just copy over the members you care about.

You cannot do this with a derived class, although this may be an X / Y Problem . To achieve what you are trying to achieve in your test case can be done using a wrapper 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; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM