在C#中是否可以将基类对象数组显式转换为其派生类对象数组之一?我有从类A派生的类C,我正在尝试将基类对象数组转换为派生类对象数组,但它返回返回null值。
public interface I
{
public string Name;
public string Id;
}
public class A
{
public string name;
public string id;
}
public class B: A,I
{
public string Name
{
get { return name; }
set{name= value;}
}
public string Id
{
get { return id; }
set{id= value;}
}
}
A[] baseClassList= GetValues();
B[] derivedClassList= baseClassList as B[];---THIS IS RETURNING NULL
我该如何解决这个问题?任何帮助表示赞赏。
答案 0 :(得分:5)
你可以很容易地使用Linq从B[]
创建一个baseClassList
,但它不会像演员一样简单。
B[] derivedClassList = baseClassList.OfType<B>().ToArray();
编辑:或者 - 如果您要转换数组的内容,我建议您使用复制构造函数。
public B(A source)
{
Name = source.name;
Id = source.id;
}
然后你可以这样转换:
B[] derivedClassList = baseClassList.Select(e => e is B ? (B)e : new B(e)).ToArray();
答案 1 :(得分:3)
为什么不这样做呢?
假设baseClassList
类型的A
个对象集合都是B
类型的真正对象。
B[] derivedClassList = baseClassList.Cast<B>().ToArray();
答案 2 :(得分:1)
这不适用于这个例子(但是如果它对其他人有用的话,我会留下答案)
var newArray = Array.ConvertAll(array, item => (NewType)item);
(从C# Cast Entire Array?无耻地被盗)
答案 3 :(得分:0)
不,你不能这样转换它,除非您尝试转换的数组实际上是B[]
之前被转换为A[]
。
A[] source = new A[10];
B[] target = (B[])source; // won't work;
A[] source = new B[10]; // B[] cast to A[], thanks to array covariance
B[] target = (B[])source; // will work fine
答案 4 :(得分:0)
我怀疑即使这是可能的。然而,通过协方差和逆变的名称在泛型中存在类似的概念。有关详细信息,请参阅此链接
http://msdn.microsoft.com/en-us/library/dd799517(v=vs.110).aspx
您尝试应用的概念是逆变的一个例子。
答案 5 :(得分:0)
这在铸造意义上是不可能的,因为A is B
是false
。但是,如果您知道它可以工作,那么没有什么能阻止您创建转换方法并使用它。
我确实需要进行一些更改(您的原始代码无法编译),但这应该引导您朝着可行的方向发展。
public interface I {
string AnotherProperty { get; }
}
public class A {
public string Name { get; set; }
public string Id { get; set; }
}
public class B : A, I {
public string AnotherProperty { get; set; }
}
public static class BExtensions {
public static B[] FromAArray(this A[] array) {
var bList = new List<B>();
foreach (var a in array) {
bList.Add(new B() { Id = a.Id, Name = a.Name, AnotherProperty = String.Empty });
}
return bList.ToArray();
}
}
class Program {
static void Main(string[] args) {
A[] baseClassList = { new A { Name = "Bob", Id = "1" }, new A { Name = "Smith", Id = "2"}};
B[] derivedClassList = baseClassList.FromAArray();
}
}
答案 6 :(得分:0)
轻松
string[] names = { "alpha" , "bravo" , "charlie" , "delta" , "echo" ,
"foxtrot" , "golf" , "hotel" , "india" , "juliet" ,
"kilo" , "lima" , "mike" , "november" , "oscar" ,
"poppa" , "quebec" , "romeo" , "sierra" , "tango" ,
"uniform" , "victor" , "whisky" , "x-ray" , "yankee" ,
"zulu" ,
} ;
A[] As = Enumerable
.Range(0,names.Length)
.Select( x => new B{ Id = x.ToString() , Name=names[x] } )
.Cast<A>()
.ToArray()
;
B[] Bs = As.Cast<B>().ToArray() ;
I[] Is = As.Cast<I>().ToArray() ;
答案 7 :(得分:0)
不使用Linq的快速高效解决方案:
//
///<summary>Create an array of a derived class from a list of a base class. Array elements may be null, if the cast was not possible.</summary>
public static D[] ToArray<T, D>( this IList<T> list ) where D : class {
if ( !list.IsFilled() ) return null;
var a = new D[ list.Count ];
for ( int i = 0; i < list.Count; i++ ) {
a[ i ] = list[ i ] as D;
}
return a;
}
使用示例:
return result.ToArray<Member, User>();