2015-11-23 1 views
-1

У меня есть два класса A и B. Оба имеют большинство свойств, оба имеют пару разных полей. Теперь используйте любой из классов на основе некоторого условия. Используя их общее свойство. Я не могу изменить схему использования наследования.Как иметь концепцию какого-либо динамического класса

например

public class A 
{ 
    public string field1 { get; set; }; 
    public string field2 { get; set; }; 
    public string field3 { get; set; }; 
    public string field4 { get; set; }; 
    public string field5 { get; set; }; 
    public string field6 { get; set; }; 
    public string field7 { get; set; }; 
    public string field8 { get; set; }; 
    public string anotherA1 { get; set; }; 
    public string anotherA2 { get; set; }; 
} 
public class B 
{ 
    public string field1 { get; set; }; 
    public string field2 { get; set; }; 
    public string field3 { get; set; }; 
    public string field4 { get; set; }; 
    public string field5 { get; set; }; 
    public string field6 { get; set; }; 
    public string field7 { get; set; }; 
    public string field8 { get; set; }; 
    public string anotherB1 { get; set; }; 
    public string anotherB2 { get; set; }; 
} 

A a = new A(); 
B b = new B(); 
dynamic d; 

if(isDo) 
    d= a; 
else 
    d= b; 

string strField = d.field1; 
string test = d.field3; 

Скажите, пожалуйста, лучший способ для достижения этой цели.

+0

Вы заявляете, что вы не можете использовать наследование, но попробовали ли вы использовать интерфейс? – Chawin

+0

Почему бы не создать общий базовый класс? –

+0

Потому что Класс уже есть. Я не хочу использовать какую-либо другую концепцию с nw. –

ответ

1

Если вы не можете изменять базовые классы можно создавать новые дочерние классы, которые реализуют общий интерфейс. Но вы должны скопировать значения свойств в конструкторе.

void Main() 
{ 
    var a = new A(){ Name = "A" }; 
    var b = new B(){ Name = "B" }; 

    INameProvider provider = new BNext(b); 
    //... 
} 

//original classes 
public class A{ 

    public string Name { get; set; } 
} 

public class B{ 

    public string Name { get; set; } 
    public string Id { get; set; } 
} 

//common interface 
public interface INameProvider { 
    string Name { get; set; } 
} 

//adapters 
public class ANext : A, INameProvider 
{ 
    public ANext(A a) 
    { 
     this.Name = a.Name;  
    } 
} 

public class BNext : B, INameProvider 
{ 
    public BNext(B b) 
    { 
     this.Name = b.Name; 
     this.Id = b.Id; 
    } 
} 
1

Вы должны научиться наследование в ООП:

public class Common 
{ 
    public string field1 { get; set; }; 
    public string field2 { get; set; }; 
    public string field3 { get; set; }; 
    public string field4 { get; set; }; 
    public string field5 { get; set; }; 
    public string field6 { get; set; }; 
    public string field7 { get; set; }; 
    public string field8 { get; set; }; 
} 
public class A : Common 
{ 
    public string anotherA1 { get; set; }; 
    public string anotherA2 { get; set; }; 
} 
public class B : Common 
{ 
    public string anotherB1 { get; set; }; 
    public string anotherB2 { get; set; }; 
} 

A a = new A(); 
B b = new B(); 
Common d; 

if(isDo) 
    d= a; 
else 
    d= b; 

string strField = d.field1; 
string test = d.field3; 
+0

У меня уже есть класс, использующий LINQ (у них может быть и другой порядок), я не хочу их беспокоить. –

+0

Итак, вы можете определить интерфейс вместо класса – tdat00

1

Если вы не можете изменить сами классы, и вы абсолютно хотите иметь общий интерфейс, вам нужно написать свой собственный Adapters.

+1

Можете ли вы объяснить мне пример, как я могу достичь в приведенном выше примере без изменения класса? –

1

Я думаю, что ваша проблема лучше всего решить путем ditching dynamic в целом и с помощью интерфейса.

public interface IFoo 
{ 
    string field1 { get; set; } 
    string field2 { get; set; } 
    string field3 { get; set; } 
    //etc... 
} 

public class A : IFoo 
{ 
    public string field1 { get; set; } 
    public string field2 { get; set; } 
    public string field3 { get; set; } 
    //...etc 
    public string anotherA1 { get; set; } 
    public string anotherA2 { get; set; } 
} 

public class B : IFoo 
{ 
    public string field1 { get; set; } 
    public string field2 { get; set; } 
    public string field3 { get; set; } 
    //...etc 
    public string anotherB1 { get; set; } 
    public string anotherB2 { get; set; } 
} 

Итак, теперь вы можете:

IFoo obj = isDo ? (IFoo)new A() : (IFoo)new B(); 
string strField = d.field1; 
string test = d.field3; 
+0

Я не могу переместить мое поле в интерфейс, потому что в порядке LINQ свойства разные. –

+0

@KaranGandhi Какой «порядок» собственности? Что это вообще значит? – spender

+0

В Linq Entity Framework это очень важно, он определяет ранг столбца в базе данных. –

2

Если вы хотите отобразить из одного типа в другой, где типы не связаны между собой по наследству, но имеют ряд широко названных свойств, вы можете использовать AutoMapper.

Вы можете использовать NuGet для добавления AutoMapper в проект. Для ваших образцов классов, вы можете карту от одного к другому, например, так:

using System; 

namespace Demo 
{ 
    public class A 
    { 
     public string field1 { get; set; } 
     public string field2 { get; set; } 
     public string field3 { get; set; } 
     public string field4 { get; set; } 
     public string field5 { get; set; } 
     public string field6 { get; set; } 
     public string field7 { get; set; } 
     public string field8 { get; set; } 
     public string anotherA1 { get; set; } 
     public string anotherA2 { get; set; } 
    } 

    public class B 
    { 
     public string field1 { get; set; } 
     public string field2 { get; set; } 
     public string field3 { get; set; } 
     public string field4 { get; set; } 
     public string field5 { get; set; } 
     public string field6 { get; set; } 
     public string field7 { get; set; } 
     public string field8 { get; set; } 
     public string anotherB1 { get; set; } 
     public string anotherB2 { get; set; } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      A a = new A {field1 = "A1", field2 = "A2", field3 = "A3"}; 

      AutoMapper.Mapper.CreateMap<A, B>(); 
      B b = AutoMapper.Mapper.Map<B>(a); // Copies fields from a to b 

      Console.WriteLine(b.field1); // Prints "A1" 
     } 
    } 
} 
+1

Я стал свидетелем столь многих злоупотреблений автоматом, что я бы почти повсеместно рекомендовал, чтобы его избегали, потому что ленивые разработчики любят злоупотреблять им.C# не является javascript, и использование automapper, чтобы обойти это, чтобы включить утиную печать, очень похоже на другое злоупотребление для меня. – spender

+0

@spender Я предполагаю, что это было бы экуменическим вопросом. :) (Мы не используем его здесь, но для использования только с DTO, когда вы не можете изменить существующие классы (как говорит OP), это, вероятно, не слишком ужасно.) –

+0

Определенно экуменический вопрос! [Это] (http://blog.alanta.nl/2015/04/automapper-is-evil.html) - интересное чтение по этому вопросу от священника атеизма automapper. – spender

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