Initialize base class in .NET

2019-04-06 09:36发布

How do I go about if I need to initialize an object's base with existing object? For example, in this scenario:

public class A
{
    public string field1;
    public string field2;
}

public class B : A
{
    public string field3;
    public void Assign(A source)
    {
        this.base = source; // <-- will not work, what can I do here?
    }
}

Assign() method can, obviously assign values to the base class field-by-field, but isn't there a better solution? Since class B inherits from A, there must be a way to just assign A to the B.base

In C++ this would be a trivial thing to do, but I can't seem to grasp how to do this in .NET

标签: c# .net oop
10条回答
SAY GOODBYE
2楼-- · 2019-04-06 10:14

No the syntax you are trying is not possible in C# .NET you need to do.

public void Assign(A source) {
    field1 = source.field1;
    field2 = source.field2; 
}
查看更多
够拽才男人
3楼-- · 2019-04-06 10:14

Why would you need to? By declaring a new B, the CLR automatically calls the constructors for both classes.

B myB = new B();

B new has the fields of both classes. However, you should declare them with an initializer unless you like nulls:

public string field1 = "";
public string field2 = string.Empty;
查看更多
啃猪蹄的小仙女
4楼-- · 2019-04-06 10:17

Unfortunately base is readonly.

[Edit]
Well perhaps not so unfortunate. The relationship between a base class and a child class is IS-A not HAS-A. By allowing a child class to change the instance of the base class you are allowing the child class to change its own reference since it IS-A base class. If you truly need this functionality then I would suggest you change your inheritance model to reflect what you truly want to do.

Something like this:

public class A
{
    public string field1;
    public string field2;
}

public class B
{
    public string field3;
    public A a;

    public void Assign(A source)
    {
        this.a = source;
    }
}

seems more appropriate and has clearer meaning and functionality.

查看更多
姐就是有狂的资本
5楼-- · 2019-04-06 10:17

Wrong question. You're obviously abusing inheritance here. Try to refactor it, so that you keep a reference to A as a member field. If you need polymorphism, consider having common base class or better yet - an interface.

查看更多
叼着烟拽天下
6楼-- · 2019-04-06 10:21

Is the intent that these fields will be initialized once during object construction, or could "Assign" be called multiple times during an object's lifetime? If the latter, you can disregard the rest of this :)

Andrew's distinction between IS-A and HAS-A is an important one; if the relationship really is a HAS-A, his composition solution is the way to go.

If an IS-A relationship makes more sense (and you are able to modify A), a copy constructor might be a good idea:

public class A
{
    public string field1;
    public string field2;

    public A(A copyFrom)
    {
        this.field1 = copyFrom.field1;
        this.field2 = copyFrom.field2;
    }
}

public class B : A
{
    public string field3;

    public B(A source)
        : base(source)
    {
    }
}

You end up having to copy each of A's properties, but the responsibility for doing so resides in A where it belongs.

查看更多
We Are One
7楼-- · 2019-04-06 10:28
    [TestMethod]
    public void TestMethod()
    {
        A a = new A();
        a.field1 = "test";
        string xml = Serialize(a);
        xml = xml.Replace("A", "B");
        B b = Deserialize(xml);

        Assert.AreEqual("test", b.field1);
    }

    public string Serialize(A a)
    {
        System.IO.StreamReader streamReader = null;
        System.IO.MemoryStream memoryStream = null;
        try
        {
            memoryStream = new System.IO.MemoryStream();
            XmlSerializer serializer = new XmlSerializer(typeof(A));
            serializer.Serialize(memoryStream, a);
            memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
            streamReader = new System.IO.StreamReader(memoryStream);
            return streamReader.ReadToEnd();
        }
        finally
        {
            if ((streamReader != null))
            {
                streamReader.Dispose();
            }
            if ((memoryStream != null))
            {
                memoryStream.Dispose();
            }
        }
    }

    public static B Deserialize(string xml)
    {
        System.IO.StringReader stringReader = null;
        try
        {
            stringReader = new System.IO.StringReader(xml);
            XmlSerializer serializer = new XmlSerializer(typeof(B));
            return ((B)(serializer.Deserialize(System.Xml.XmlReader.Create(stringReader))));
        }
        finally
        {
            if ((stringReader != null))
            {
                stringReader.Dispose();
            }
        }
    }
查看更多
登录 后发表回答