Скопировать класс в другой? - PullRequest
8 голосов
/ 15 января 2010

у меня

class A
{
    public int a;
    public string b;
}

Как я могу скопировать A в другой A? В C ++ я знаю, что могу сделать *a1 = *a2;. Есть ли что-то подобное в C #? Я знаю, что мог бы написать общее решение, используя рефлексию, но я надеюсь, что что-то уже существует.

Я подумываю изменить А на обнуляемую структуру.

Шаг 2 Мне нужно сделать

class B : A {}
class C : A {}

и скопировать базовые данные из B в C.

Ответы [ 8 ]

8 голосов
/ 15 января 2010

Я использовал двоичную сериализацию. По сути, сериализовать экземпляр в поток памяти. Затем десериализовать его из потока памяти. У вас будет точная двоичная копия. Это будет глубокая копия, а не мелкая копия.

class a = new ClassA();

class b = MySerializationMethod(a);

Для мелкой копии вы можете использовать Object.MemberwiseClone

7 голосов
/ 15 января 2010

Вот простой код, который работает с любым классом, а не только с базовым.

    public static void DuckCopyShallow(this Object dst, object src)
    {
        var srcT = src.GetType();
        var dstT= dst.GetType();
        foreach(var f in srcT.GetFields())
        {
            var dstF = dstT.GetField(f.Name);
            if (dstF == null)
                continue;
            dstF.SetValue(dst, f.GetValue(src));
        }

        foreach (var f in srcT.GetProperties())
        {
            var dstF = dstT.GetProperty(f.Name);
            if (dstF == null)
                continue;

            dstF.SetValue(dst, f.GetValue(src, null), null);
        }
    }
4 голосов
/ 15 января 2010
4 голосов
/ 15 января 2010

Предполагая, что A - простой класс, вы можете сделать

A newA = instanceOfA.MemberwiseClone();

MemberwiseClone () - это неглубокая копия, поэтому, если ваш класс становится сложным, со свойствами, которые также являются ссылочными типами, это не будет работать для вас.

3 голосов
/ 15 января 2010

Добавьте соответствующие конструкторы:

class Foo
{
    public Foo(int a, string b)
    {
        A = a;
        B = b;
    }

    public Foo(Foo other)
    {
        A = other.A;
        B = other.B;
    }

    public int A { get; set; }
    public string B { get; set; }
}

Вам также следует подумать о том, чтобы сделать его неизменным, особенно если вы планируете превратить его в структуру. Изменчивые структуры - это зло.

Наконец, когда вы наследуете от класса, вам не нужно копировать членов из базового класса в подкласс.

3 голосов
/ 15 января 2010

есть интерфейс ICloneable, который предлагает метод Clone().

Клонировать в MSDN.

2 голосов
/ 15 января 2010

Мы успешно использовали этот код:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace Utility {
    internal static class ObjectCloner {
        public static T Clone<T>(T obj) {
            using (MemoryStream buffer = new MemoryStream()) {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(buffer, obj);
                buffer.Position = 0;
                T temp = (T)formatter.Deserialize(buffer);
                return temp;
            }
        }
    }
}

Могут быть и другие методы, которые работают лучше, но, возможно, это поможет вам

Chris

0 голосов
/ 15 января 2010

Вы можете клонировать, вы можете определить конструктор копирования. Зачем менять класс на struct только потому, что в C ++ вы можете сделать что-то из 10 символов. C # отличается. Структуры имеют свои преимущества и недостатки.

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