我在第三方DLL中有一个类。
Class A
{
}
我需要装饰它,所以我创建了它的本地实例并使用它
class B
{
}
DLL包含一个函数,它给出了A的列表。但是如果我尝试使用它如下
B listofB = Dll.FindAllA()
我收到错误无法将DLL.A隐式转换为Proj.B
这两个类的结构没有区别。我该如何转换它?
答案 0 :(得分:5)
如果A
和B
没有任何共同之处(除了看起来相同),编译器就不走运了。选项:
ToA
等扩展方法我会首先选择前两个选项。请注意,使用List<T>
,您可以使用全部转换,即:
List<A> orig = ...
List<B> copy = orig.ConvertAll(a => (B)a);// assumes a conversion operator exists
对于其他类型,LINQ Select
方法等同于ConvertAll
。
答案 1 :(得分:1)
我认为你自己部分给出了答案,因为你在谈论'装饰'。以装饰A的方式实现B
或B
的后代,并在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
}
现在有了这个适配器,您可以更改As到Bs的列表:
B[] listofB = Dll.FindAllA().Select(a => new AToBAdapter(a) as B).ToArray();
答案 2 :(得分:1)
你可以在B类上重载强制转换操作符:
public static implicit operator B(A e)
{
return new B(e.Property1, e.Property2);
}
顺便说一句,你应该只使用隐式,如果没有数据丢失而且你不期望异常,否则改为显式:(B)A
答案 3 :(得分: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);