问题
I have two classes that have no connection to one another :
public class A
{
public String Address {get;set}
}
public class B
{
public String Address {get;set}
}
List<A> addressList = DB.Addresses.GetAll();
When I do
List<B> addressListOther = addressList.Cast<B>().ToList();
the output is :
Additional information: Unable to cast object of type 'A' to type 'B'.
Any idea how to fix that ?
回答1:
You can use Select()
instead of that way:
List<B> addressListOther = addressList.Select(a => new B { Address = a.Address}).ToList();
Or you can override explicit operator
in class B
:
public static explicit operator B(A a) // explicit A to B conversion operator
{
return new B { Address = a.Address };
}
And, then:
List<B> addressListOther = aList.Select(a => (B)a).ToList();
The reason of this exception:
Cast
will throw InvalidCastException
, because it tries to convert A
to object
, then cast it to B
:
A myA = ...;
object myObject = myA ;
B myB= (B)myObject; // Exception will be thrown here
The reason of this exception is, a boxed value can only be unboxed to a variable of the exact same type.
Additional Information:
Here is the implemetation of the Cast<TResult>(this IEnumerable source) method, if you interested:
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);
}
As you see, it returns CastIterator
:
static IEnumerable<TResult> CastIterator<TResult>(IEnumerable source) {
foreach (object obj in source) yield return (TResult)obj;
}
Look at the above code. It will iterate over source with foreach
loop, and converts all items to object
, then to (TResult)
.
回答2:
They do not inherit from each other so you can't do that. The Cast<T>
iterates over the collection and tries to cast the items to the specified type.
If you do the following you will fail to0:
A a = new A { Address = "a"};
B b = (B)a; // Compile error of: Cannot convert type A to B
Instead use Select
to project new B
items.
List<B> addressListOther = addressList.Select(a => new B { Address = a.Address}).ToList();
Another way is to override the implicit operator
in class A
:
public static implicit operator B(A a)
{
return new B { Address = a.Address };
}
And then the followingcode will word:
List<A> aList = new List<A> { new A { Address = "a" } };
List<B> bList = aList.Select(a => (B)a).ToList();
回答3:
The simpliest way for me is to introduce a superclass.
public class ClassWithAddress
{
public string Address{get;set;}
}
Then you'll derive every class from that class and delete the address property like this:
public class A : ClassWithAddress
{
}
public class B : ClassWithAddress
{
}
After that you can do your list operations concerning the Address Property with the superclass ClassWithAddress
.
来源:https://stackoverflow.com/questions/40148491/cast-class-a-to-class-b-without-generics