2010-01-14 4 views
7

ЯСкопируйте класс в другой?

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

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

Я рассматриваю возможность изменения A на nullable struct.

Шаг 2 я вам нужно сделать

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

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

+1

Почему вам нужно сделай это? –

+0

Вы уже спрашивали об этом здесь: http://stackoverflow.com/questions/2067725/best-way-to-convert-a-shared-base – Amy

+0

@ yodaj007: Этот человек очищает свою идею от этого вопроса. Я уже проголосовал за закрытие старого. –

ответ

6

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

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

Если предположить, что это просто простой класс, вы можете сделать

A newA = instanceOfA.MemberwiseClone(); 

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

+0

Хотя это не так быстро, как неоаналитический подход. –

+0

Согласовано. Однако он может быть более удобным и масштабируемым, чем пользовательский подход. – womp

0

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

3

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

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

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

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

+0

+1 Если бы у меня было достаточно голосов сегодня. Неизменяемость не подразумевает никаких заданных свойств, не так ли? –

+0

@lpthnc: 'private set' сделал бы это. –

+0

Спасибо. Как бы вы заявили, что если вы хотите, чтобы все стали публичными - в одной строке или отдельно? –

7

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

class a = new ClassA(); 

class b = MySerializationMethod(a); 

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

+0

+1 для этого метода. Мы использовали это много раз, и он отлично работает. – womp

+0

Похоже, что Object.MemberwiseClone работает только с двумя классами одинаковы и внутри метода класса? Как я могу программировать MySerializationMethod? Кажется, я буду использовать отражение. – 2010-01-14 22:35:28

+0

кто-то разместил его ниже: http://www.c-sharpcorner.com/UploadFile/sd_surajit/cloning05032007012620AM/cloning.aspx не требуется никакого отражения –

2

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

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

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

Крис

Смежные вопросы