2014-02-06 2 views
0

Я ищу лучшее решение, например: (позволяет говорить с помощью псевдокода!)Скопируйте все параметры, которые реализуют этот же интерфейс

public interface IObj 
{ 
    string propertyX; 
    string propertyY; 
} 

public class ObjectA : IObj 
{ 
    string propertyX; 
    string propertyY; 
} 

public class ObjectB: IObj 
{ 
    string propertyX; 
    string propertyY; 

    public ObjectB(ObjectA) 
    { 
     // HERE I WANT TO GET ALL Properties that are from ObjectA that is from IObj 
     // without assigne this.propertyX=ObjectA.propertyX 
    } 
} 

есть ли простой способ сделать это?

+0

Плохая идея, любой «автомагнитный» золь скорее всего, заставит ваше приложение проявлять бум каждый раз, когда вы касаетесь ObjectA * или * ObjectB * или * самого IObj – Alex

+0

Разве вы не должны «ObjectB: ObjectA'? – TheGeekZn

+0

проблема в том, что я не могу редактировать ObjectA и интерфейс Мне просто нужно скопировать все свойства в ObjectB, но ObjectA имеет ... около 300 параметров из интерфейса IObj –

ответ

2

Все, что вам нужно сделать, чтобы достичь своей цели является: - получить все свойства от IObj интерфейса - получить все свойства из ObjectA класса - получить все свойства из ObjectB класса - присоединиться к коллекции по именам свойств из IObj интерфейса и пара свойств из ObjectA со свойствами из ObjectB - итерируют пары и называют GetValue() по свойствам от ObjectA и SetValue() по свойствам от ObjectB

Это то, что я почесал в LINQPad:

void Main() 
{ 
    var a = new ObjectA 
    { 
     propertyX = Guid.NewGuid().ToString(), 
     propertyY = Guid.NewGuid().ToString() 
    }; 
    var b = new ObjectB(a); 
    b.Dump(); 
} 


public interface IObj 
{ 
    string propertyX{get;set;} 
    string propertyY{get;set;} 
} 

public class ObjectA : IObj 
{ 
    public string propertyX{get;set;} 
    public string propertyY{get;set;} 
} 

public class ObjectB: IObj 
{ 
    public string propertyX{get;set;} 
    public string propertyY{get;set;} 

    public ObjectB(ObjectA a) 
    { 
     var properties = typeof(IObj).GetProperties(); 
     var objAProperties = typeof(ObjectA).GetProperties(); 
     var objBProperties = typeof(ObjectB).GetProperties(); 
     var common = from p in properties 
        from propA in objAProperties 
        from propB in objBProperties 
        where p.Name == propA.Name && p.Name == propB.Name 
        select Tuple.Create(propA, propB); 
     foreach(var tuple in common) 
     { 
      var value = tuple.Item1.GetValue(a); 
      tuple.Item2.SetValue(this, value); 
     } 
    } 
} 

СПУСТЯ EDIT

Чтобы создать метод расширения интерфейса:

public static class ObjExtesions 
{ 
    public static void CopyProperties(this IObj source, IObj destination) 
    { 
     var properties = typeof(IObj).GetProperties(); 
     var objAProperties = source.GetType().GetProperties(); 
     var objBProperties = destination.GetType().GetProperties(); 
     var common = from p in properties 
        from propA in objAProperties 
        from propB in objBProperties 
        where p.Name == propA.Name && p.Name == propB.Name 
        select Tuple.Create(propA, propB); 
     foreach(var tuple in common) 
     { 
      var value = tuple.Item1.GetValue(source); 
      tuple.Item2.SetValue(destination, value); 
     } 
    } 
} 

И потом, изменение кода в ObjectB конструктору:

public ObjectB(ObjectA a) 
{ 
    a.CopyProperties(this); 
} 
+0

это красиво! спасибо –

+0

Я не уверен в этом, но можете ли вы реализовать этот код как метод расширения интерфейса? –

+0

Нет гарантии, что свойство X в классе является единственным реализующим свойством X в интерфейсе. Вы можете просто использовать значения 'p' и значения чтения/записи двух объектов напрямую, вам не нужно находить свойства самих классов. Предполагая, конечно, что рассматриваемые классы фактически реализуют интерфейс. –

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