2011-01-18 4 views
1

В простейших для вот то, что я хочу сделать:Как преобразовать производные типы интерфейса?

interface InterfaceA 
{ 
    string var1 { get; set; } 
    string var2 { get; set; } 
} 

public class DerivedA : InterfaceA 
{ 
    public string var1 { get; set; } 
    public string var2 { get; set; } 
} 

public class DerivedB : InterfaceA 
{ 
    public string var1 { get; set; } 
    public string var2 { get; set; } 
} 

public class DoEverything 
{ 
    InterfaceA A = new DerivedA(); 
    InterfaceA B = new DerivedB(); 

    A.var1 = "Test1"; 
    A.var2 = "Test2"; 

    B = ConvertObject<DerivedB>(A); 

    write(B.var1 + ", " + B.var2); 

    // This doesn't work, I would like it to though. 
    public T ConvertObject<T>(object obj) 
    { 
     T result = (T)typeof(T).GetConstructor(new Type[] { }).Invoke(new object[] { }); 

     foreach (PropertyInfo propertyInfo in obj.GetType().GetProperties()) 
     { 
      if (propertyInfo.CanRead) 
      { 
       try 
       { 
        object value = propertyInfo.GetValue(obj, null); 
        propertyInfo.SetValue(result, value, null); 
       } 
       catch { } 
      } 
     } 

     return result; 
    } 
} 

Сейчас я должен вручную преобразовать каждое свойство в своих объектах и ​​при добавлении нового свойства я должен помнить, чтобы пойти методы преобразования и добавьте его. Я бы предпочел, чтобы это было сделано автоматически.

Любая помощь была бы принята с благодарностью.

заранее спасибо

ответ

1

Я предполагаю, что я не знаю, что вы получаете в. Почему бы вам просто не объявить конструкторы для DerivedA и DerivedB, которые используют интерфейсA для инициализации? Это было бы проще и гибче, так как каждый производный тип отвечал бы за инициализацию себя от типа интерфейса. Впоследствии вы можете добавить больше типов, реализующих интерфейс, и они будут использоваться другими классами без каких-либо дальнейших изменений.

+0

Причиной этого является мой бизнес слой имеет общий фиктивный класс, который просто получает и устанавливает каждое свойство для интерфейса. Мой реальный класс, хотя и недоступен для бизнес-уровня. Мне нужно сериализовать реальный класс и отправить его в webservice для вычислений. Я не могу сериализовать интерфейс, и мой оригинальный класс не реализован в моем бизнес-слое по причинам, которые меня расстраивают, но я не могу контролировать. Поэтому мне нужно преобразовать свой первоначальный класс в мой фиктивный класс и затем сериализовать. Добавление конструктора, использующего тип интерфейса, не помогает, потому что я мог бы так же легко ... – ClaytonHunt

+0

объявить класс как DerivedB B = новый DerivedB() {blah = A.blah и т. Д.}, Который по-прежнему требует ручного перевода от A до B – ClaytonHunt

+0

Это еще простой ответ, потому что вы работаете с известным интерфейсом. В вашем фиктивном классе реализуйте методы FromA и ToA, из которых eaxh принимает InterfaceA как один аргумент. FromA получает значения свойств из arg, ToA делает обратное. Вам не нужно отражать, если вы знаете, что такое InterfaceA. –

2

Вы можете добавить конструктор, к примеру, DerivedB, который принимает интерфейсA как аргумент.

E.g.

public class DerivedB : InterfaceA 
{ 
    public string var1 { get; set; } 
    public string var2 { get; set; } 
    public DerivedB(InterfaceA original) 
    { 
     var1 = original.var1; 
     var2 = original.var2; 
    } 
} 

Затем вы можете использовать его в качестве такового:

public class DoEverything 
{ 
    InterfaceA A = new DerivedA(); 

    A.var1 = "Test1"; 
    A.var2 = "Test2"; 

    InterfaceA B = new DerivedB(A); 
    write(B.var1 + ", " + B.var2); 
} 
+0

Это все еще оставляет за собой право обновлять все производные классы с помощью конструктора для его обработки, а затем я все же должен помнить, чтобы добавить к конструктору для каждого производного класса. – ClaytonHunt

+0

Вы можете создать абстрактный базовый класс, содержащий метод «Создать» и вызвать его (либо из DoEverything, либо из конструкторов). В любом случае вам нужно будет создавать конструкторы только для возможных «преобразовать в» классы, не обязательно во всех них. – Sklivvz

+0

Это, вероятно, маршрут, который мне придется принять, если кто-то не может помочь мне с более эффективным методом. У меня есть проблемы, но – ClaytonHunt

0

Вы должны реализовать operator overloading для обоих производных классов:

+0

Спасибо, опять же, хотя это требует модификации метода каждый раз, когда я изменяю интерфейс для включения большего количества свойств.Я действительно хочу сделать это одним выстрелом один метод, который я мог бы использовать для всех производных классов всех интерфейсов. Пока они разделяют одного и того же предка. Очевидно, я не могу преобразовать класс Cat в класс Toaster. – ClaytonHunt

+0

@ user580270: Тогда вы должны использовать отражение, но оно довольно медленное, и в любом случае - плохая идея. – abatishchev

+0

Если бы я должен был выбрать отражение, как бы реализовать это? – ClaytonHunt

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