我有一个声明如下的函数:
public static string MultiWhereToString(List<WhereCondition<T>> whereConditions)
我正在尝试传递一个名为whereAnd
的变量,其变量如下:
private List<WhereAndCondition<T>> whereAnd = new List<WhereAndCondition<T>>();
WhereAndCondition
是WhereCondition
的子类。声明如下:
public class WhereAndCondition<T> : WhereCondition<T>, IConditional where T : DatabaseObject
我的问题是,如果我尝试执行以下代码:
private List<WhereAndCondition<T>> whereAnd = new List<WhereAndCondition<T>>();
MultiWhereToString(whereAnd);
我收到以下错误:
Error 3 Argument 1: cannot convert from 'System.Collections.Generic.List<BrainStorm.WhereAndCondition<T>>' to 'System.Collections.Generic.List<BrainStorm.WhereCondition<T>>'
为什么有任何想法?我认为它与WhereCondition
类的泛型有关。
答案 0 :(得分:2)
假设:
class A {}
class A : B {}
List<B>
的对象不 List<A>
的实例。因此,您无法将List<WhereAndCondition>
投射到List<WhereCondition>
。你可以使用:
MultiWhereToString(whereAnd.OfType<WhereCondition>().ToList());
(可能还有一个涉及in
和out
方差注释的解决方案,但我对它们并不十分熟悉。)
答案 1 :(得分:2)
您的函数被定义为采用WhereCondition列表,但您将其传递给WhereAndCondition列表:
MultiWhereToString(List<WhereCondition<T>> whereConditions)
private List<WhereAndCondition<T>> whereAnd = new List<WhereAndCondition<T>>();
MultiWhereToString(whereAnd);
在.NET 4中支持列表差异有限。请参阅this question。
答案 2 :(得分:2)
必须在编译时明确知道泛型,因为它们是生成的。
为什么不使用:
private List<WhereCondition<T>> whereAnd = new List<WhereCondition<T>>();
因此,您仍然可以将WhereAndCondition
个对象添加到whereAnd
。
答案 3 :(得分:2)
您可以将WhereCondition<T>
方法中的整个MultiWhereToString
替换为仅限WhereCondition<T>
的其他通用类型。
替换:
public static string MultiWhereToString(List<WhereCondition<T>> whereConditions)
使用:
public static string MultiWhereToString<TType>(List<TType> whereConditions) where TType: WhereCondition<T>
或者改变:
private List<WhereAndCondition<T>> whereAnd = new List<WhereAndCondition<T>>();
为:
private List<WhereCondition<T>> whereAnd = new List<WhereCondition<T>>();
让继承为你照顾剩下的事。
答案 4 :(得分:2)
这似乎是一个协方差/逆转问题。
简化为:
public class WhereCondition
{
}
public class WhereAndCondition : WhereCondition
{
}
public class blah
{
public static void Blah()
{
List<WhereAndCondition> whereAnd = new List<WhereAndCondition>();
MultiWhereToString(whereAnd);
}
public static string MultiWhereToString(List<WhereCondition> whereConditions)
{
return null;
}
}
它不会起作用,因为WhereAndConditions列表无法强制转换为WhereConditions列表:
想象一下这样。你有一个长颈鹿的名单,这个方法是要求一份动物名单。
不知道他们将如何处理列表动物(比如尝试添加马),这些类型是不兼容的,但是如果你把它改成这样的话:
public static string MultiWhereToString(IEnumerable<WhereCondition> whereConditions)
{
return null;
}
然后方差可以启动,并为您提供您正在寻找的东西。
答案 5 :(得分:2)
我建议使用接口:
public static string MultiWhereToString(IEnumerable<ICondition<T>> whereConditions)
这会让你在调用这个方法时有更多的自由。