将基本类型列表转换为继承类型列表
我确信这个问题解决了上一个问题中提出的问题,但我找不到它。
C# 类中有一个方法,它将基类的通用列表作为参数。 我需要传递继承类的列表,但不确切知道如何执行此操作。 我在尝试中遇到错误。 下面是示例代码来说明这一点:
public class A
{
public static void MethodC(List<A>)
{
// Do Something here with the list
}
}
public Class B : A
{
// B inherits from A, A is the Base Class
}
// Code utilizing the above method
List<B> listOfB = new List<B>();
A.MethodC( (List<A>) listOfB ); // Error: this does not work
A.MethodC( listOfB.ToList<typeof(A)>() ); // Error: this does not work
A.MethodC( listOfB.ConvertAll<A>(typeof(A)) ); // Error: this does not work
// how can I accomplish this? It should be possible I would think
注意:这是我最终的工作方法作为参考。 我对我的问题得到了更好的解决方案,但从技术上讲,这并不是问题的答案,因为我的问题措辞不正确。
public static DataTable
ObjectCollectionToDataTable<GLIST>
(List<GLIST> ObjectCollection) where GLIST
: BaseBusinessObject
{
DataTable ret = null;
if (ObjectCollection != null)
{
foreach ( var b in ObjectCollection)
{
DataTable dt = b.ToDataTable();
if (ret == null)
ret = dt.Clone();
if (dt.Rows.Count > 0)
ret.Rows.Add(dt.Rows[0].ItemArray);
}
}
return ret;
}
I would be certain that this question addresses something that would have been brought up in a previous question, but I was unable to find it.
There is a method in a C# class that takes as a parameter a generic List of a Base Class. I need to pass a list of an inherited class and do not know exactly how to do this. I am getting an error in my attempts. Below is sample code to illustrated this:
public class A
{
public static void MethodC(List<A>)
{
// Do Something here with the list
}
}
public Class B : A
{
// B inherits from A, A is the Base Class
}
// Code utilizing the above method
List<B> listOfB = new List<B>();
A.MethodC( (List<A>) listOfB ); // Error: this does not work
A.MethodC( listOfB.ToList<typeof(A)>() ); // Error: this does not work
A.MethodC( listOfB.ConvertAll<A>(typeof(A)) ); // Error: this does not work
// how can I accomplish this? It should be possible I would think
Note: Here is my final working Method as a reference. I got an even better solution to my problem, but technically it wasn't an answer to the question, since my question was phrased impropertly.
public static DataTable
ObjectCollectionToDataTable<GLIST>
(List<GLIST> ObjectCollection) where GLIST
: BaseBusinessObject
{
DataTable ret = null;
if (ObjectCollection != null)
{
foreach ( var b in ObjectCollection)
{
DataTable dt = b.ToDataTable();
if (ret == null)
ret = dt.Clone();
if (dt.Rows.Count > 0)
ret.Rows.Add(dt.Rows[0].ItemArray);
}
}
return ret;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果你有 linq 可用,你可以这样做
If you have linq available you can do
你不能这样做。 要理解为什么不允许这样做,想象一下如果在将
List
转换为List 后在
。List
上调用Add
会发生什么。此外,暗示 C# 4.0 将有所不同的答案是错误的。 永远不会修改列表来允许您执行此操作。 只有
IEnumerable
会 - 因为它不允许将项目添加到集合中。更新:它在您所寻求的解决方案中起作用的原因是因为您不再传递相同的列表。 您正在创建一个全新的列表,它是原始列表的副本。 这就是为什么我要求修改列表; 如果
MethodC
对列表中的项目数量进行了更改,这些更改将针对副本进行,而不是对原始列表进行。我认为最适合您的解决方案如下:
请注意,使用此解决方案,您如何可以将
List
直接传递给MethodC
而无需进行那种奇怪的转换首先。 所以没有不必要的复制。之所以有效,是因为我们告诉
MethodC
接受从A
派生的任何内容的列表,而不是坚持它必须是的列表一个。
You cannot do that. To understand why it is not allowed, imagine what would happen if
Add
was called on aList<Derived>
after it had been cast to aList<Base>
.Also, the answers implying that C# 4.0 will be different are wrong. List will never be modified to allow you to do this. Only
IEnumerable
will - because it does not allow items to be added to the collection.Update: The reason it works in the solution you've gone for is because you're no longer passing the same list. You're creating a whole new list which is a copy of the original. This is why I asked about modifying the list; if
MethodC
makes changes to the number of items on the list, those changes would be made to a copy, not the original list.I think the ideal solution for you is as follows:
Notice how, with this solution, you can pass a
List<B>
directly toMethodC
without needing to do that weird conversion on it first. So no unnecessary copying.The reason this works is because we've told
MethodC
to accept a list of anything that is derived fromA
, instead of insisting that it must be a list ofA
.您正在解决当前 C# 版本中缺乏协变性的问题。 这是一种方法:
You are addressing the lack of covariance in the current C# version. Here is one way of doing it:
这是一个答案,它将排除列表中错误类型的任何对象。 在我看来,这是一种更安全的方法:
OfType 方法将排除错误派生类的项目,而 Cast 将抛出错误。
Here is an answer that will exclude any objects in your list of the wrong type. This is a much safer way in my opinion:
The OfType method will exclude items of the wrong derived class where as the Cast will throw an error.