我有两个彼此没有联系的类:
public class A
{
public String Address {get;set}
}
public class B
{
public String Address {get;set}
}
List<A> addressList = DB.Addresses.GetAll();
当我这样做时
List<B> addressListOther = addressList.Cast<B>().ToList();
输出是:
附加信息:无法投射类型&#39; A&#39;输入&#39; B&#39;。
知道如何解决这个问题吗?
答案 0 :(得分:7)
您可以使用Select()
代替:
List<B> addressListOther = addressList.Select(a => new B { Address = a.Address}).ToList();
或者您可以在课程explicit operator
中覆盖B
:
public static explicit operator B(A a) // explicit A to B conversion operator
{
return new B { Address = a.Address };
}
然后:
List<B> addressListOther = aList.Select(a => (B)a).ToList();
此异常的原因:
Cast
会抛出InvalidCastException
,因为它会尝试将A
转换为object
,然后将其转换为B
:
A myA = ...;
object myObject = myA ;
B myB= (B)myObject; // Exception will be thrown here
此异常的原因是, 盒装值 只能取消装入 完全相同类型 <的变量/ strong>即可。
其他信息:
以下是Cast<TResult>(this IEnumerable source)
方法的实现,如果您感兴趣:
public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source) {
IEnumerable<TResult> typedSource = source as IEnumerable<TResult>;
if (typedSource != null) return typedSource;
if (source == null) throw Error.ArgumentNull("source");
return CastIterator<TResult>(source);
}
如您所见,它返回CastIterator
:
static IEnumerable<TResult> CastIterator<TResult>(IEnumerable source) {
foreach (object obj in source) yield return (TResult)obj;
}
看看上面的代码。它将使用foreach
循环遍历源代码,并将所有项目转换为object
,然后转换为(TResult)
。
答案 1 :(得分:4)
他们不会相互继承,所以你不能这样做。 Cast<T>
遍历集合并尝试将项目转换为指定的类型。
如果您执行以下操作,则无法执行0:
A a = new A { Address = "a"};
B b = (B)a; // Compile error of: Cannot convert type A to B
而是使用Select
来投放新的B
项。
List<B> addressListOther = addressList.Select(a => new B { Address = a.Address}).ToList();
另一种方法是覆盖班级implicit operator
中的A
:
public static implicit operator B(A a)
{
return new B { Address = a.Address };
}
然后以下代码将说出:
List<A> aList = new List<A> { new A { Address = "a" } };
List<B> bList = aList.Select(a => (B)a).ToList();
答案 2 :(得分:1)
对我来说,最简单的方法是引入一个超类。
https://JENKSIN_URL/api/json?tree=jobs[name,color,buildable,healthReport[description,score,iconUrl],builds[changeSet[items[msg,user]]]]
然后你将从该类派生每个类并删除地址属性,如下所示:
public class ClassWithAddress
{
public string Address{get;set;}
}
之后,您可以使用超类public class A : ClassWithAddress
{
}
public class B : ClassWithAddress
{
}
执行与地址属性相关的列表操作。