c#中带泛型的函数声明
本文关键字:函数 声明 泛型 | 更新日期: 2023-09-27 18:14:38
我有一个函数是这样声明的:
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
类的泛型有关。
我建议使用以下接口:
public static string MultiWhereToString(IEnumerable<ICondition<T>> whereConditions)
给定:
class A {}
class A : B {}
List<B>
的对象是而不是 List<A>
的实例。所以你不能将List<WhereAndCondition>
转换为List<WhereCondition>
。您可以使用:
MultiWhereToString(whereAnd.OfType<WhereCondition>().ToList());
(也可能有一个涉及in
和out
方差注释的解决方案,但我对它们不是很熟悉。)
你的函数被定义为接受wherandcondition List,但是你传递给它的是wherandcondition List:
MultiWhereToString(List<WhereCondition<T>> whereConditions)
private List<WhereAndCondition<T>> whereAnd = new List<WhereAndCondition<T>>();
MultiWhereToString(whereAnd);
. net 4中对列表变化的支持有限。
您可以将MultiWhereToString
方法中的整个WhereCondition<T>
替换为另一个限制为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>>();
让继承为你处理剩下的部分。
这似乎是一个协方差/逆变性问题。
简化为:
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;
}
}
它不会工作,因为wherandconditions列表不能强制转换为list of wherandconditions:
这样想。你有一个长颈鹿的列表,而这个方法是要求一个动物列表。
在不知道他们将如何处理列表动物(比如尝试添加一匹马)的情况下,类型是不兼容的,但如果您将其更改为以下内容:
public static string MultiWhereToString(IEnumerable<WhereCondition> whereConditions)
{
return null;
}
然后变化就会起作用,给你你想要的。
泛型必须在编译时显式地知道,因为它们是生成的。
为什么不用:
private List<WhereCondition<T>> whereAnd = new List<WhereCondition<T>>();
所以你仍然可以添加WhereAndCondition
对象到whereAnd
。