наследование c # и низведение иерархии наследования - PullRequest
4 голосов
/ 27 января 2011

Я хотел бы создать новый объект типа B из существующего объекта типа A. B наследуется от A. Я хотел бы убедиться, что все значения свойств в объекте типа A скопированы в объект типа B. Каков наилучший метод для достижения этой цели?

class A
{
     public int Foo{get; set;}
     public int Bar{get; set;}
}

class B : A
{
    public int Hello{get; set;}
}


class MyApp{
    public A getA(){
         return new A(){ Foo = 1, Bar = 3 };
    }

    public B getB(){
         A myA = getA();
         B myB = myA as B; //invalid, but this would be a very easy way to copy over the property values!
         myB.Hello = 5;
         return myB;
    }

    public B getBAlternative(){
         A myA = getA();
         B myB = new B();

         //copy over myA's property values to myB
         //is there a better way of doing the below, as it could get very tiresome for large numbers of properties
         myB.Foo = myA.Foo;
         myB.Bar = myA.Bar;

         myB.Hello = 5;
         return myB;
    }
}

Ответы [ 3 ]

4 голосов
/ 27 января 2011
class A {
    public int Foo { get; set; }
    public int Bar { get; set; }

    public A() { }

    public A(A a) {
        Foo = a.Foo;
        Bar = a.Bar;
    }
}

class B : A {
    public int Hello { get; set; }

    public B()
        : base() {

    }

    public B(A a)
        : base(a) {

    }
}

EDIT

Если вы не хотите копировать каждое свойство, вы можете сделать A и B сериализуемыми и сериализовать ваш экземпляр A (скажем, в Stream, а не файл) и инициализировать ваш экземпляр B с ним. Но я предупреждаю вас, это отвратительно и накладывает немало накладных расходов:

A a = new A() {
    Bar = 1,
    Foo = 3
};

System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(typeof(A));
System.IO.Stream s = new System.IO.MemoryStream();
xs.Serialize(s, a);

string serial = System.Text.ASCIIEncoding.ASCII.GetString(ReadToEnd(s));
serial = serial.Replace("<A xmlns", "<B xmlns");
serial = serial.Replace("</A>", "</B>");

s.SetLength(0);
byte[] bytes = System.Text.ASCIIEncoding.ASCII.GetBytes(serial);
s.Write(bytes, 0, bytes.Length);
s.Position = 0;

xs = new System.Xml.Serialization.XmlSerializer(typeof(B));
B b = xs.Deserialize(s) as B;

Более подробную информацию о ReadToEnd можно получить здесь .

3 голосов
/ 27 января 2011

Вы можете определить явный оператор приведения для B:

   public static explicit operator B(A a) 
   {
     B b = new B();
     b.Foo = a.Foo;
     b.Bar = a.Bar;
     b.Hello = 5;
     return b;
   }

так что вы можете сделать:

B myB = (B)myA;
0 голосов
/ 27 января 2011

Это невозможно в OO-механизме, но AutoMapper был создан именно для этого использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...