2010-10-27 2 views
2

У меня есть класс в сторонней DLL.Как Typecast список?

Class A 
{ 

} 

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

class B 
{ 

} 

библиотека DLL содержит функцию, которая дает мне список А. Но если я пытаюсь использовать его следующим

B listofB = Dll.FindAllA() 

я получил ошибку, что не может неявно преобразовать DLL.A в Proj.B

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

+3

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

+0

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

+0

@ Øyvind Bråthen: Я создаю свой собственный класс в тестовом проекте, где компилятор предлагает мне добавить DataServiceEntityAttribute в класс. Поскольку я не могу изменить код в DLL, я создал его реплику с атрибутом DataServiceEntityAttribute. – Ram

ответ

5

Если A и B не имеют ничего общего (кроме того что они выглядят то же самое), компилятор не повезло. Опции:

  • Наследование (иногда)
  • добавить оператор преобразования к одному из типов
  • добавить и т.д. метод расширения ToA если типы находятся вне вашего контроля
  • попробовать automapper
  • использования сериализации (есть способы заставить некоторые сериализаторы работать с разными именами и т. д.)

Я бы пошел на th сначала первые два варианта. Обратите внимание, что с List<T> вы можете использовать преобразовать все, т.е .:

List<A> orig = ... 
List<B> copy = orig.ConvertAll(a => (B)a);// assumes a conversion operator exists 

Для других типов, метод LINQ Select эквивалентно ConvertAll.

1

Я думаю, что вы частично сами дали ответ, потому что вы говорите об «украшении». Реализовать B или потомок B таким образом, что она украшает A и обернуть элементы возвращаемой коллекции в случаях B:

public class B 
{ 
    // Methods of B 
} 

public class AToBAdapter : B 
{ 
    A a; 

    public AToBAdapter(A a) 
    { 
     this.a = a; 
    } 

    // Override methods of B to map to A 
} 

Теперь с помощью этого адаптера на месте, вы можете изменить список Как Bs:

B[] listofB = Dll.FindAllA().Select(a => new AToBAdapter(a) as B).ToArray(); 
1

вы можете перегрузить оператор приведения на класс B:

public static implicit operator B(A e) 
{ 
    return new B(e.Property1, e.Property2); 
} 

Кстати, вы должны только нам e неявно, если не может быть потери данных, и вы не ожидаете исключения, иначе измените на явный: (B) A

0

C# является ковариантным и не поддерживает неявное преобразование коллекций. Хотя этот вопрос был рассмотрен на C# 4.0 несколько иным образом. Например, следующий код будет генерировать исключение во время компиляции

public class A 
    { 

    } 
    public class B : A 
    { 

    } 

    List<B> obj1 = new List<B>(); 
    List<A> obj2 = obj1; 

Хотя B является производным от A, неявное преобразование не будет иметь место.Он должен быть явно преобразован, как показано ниже.

List<A> obj2 = obj1.ConvertAll(b => (A)b);