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>>();

WhereAndConditionWhereCondition的一个子类。它是这样声明的:

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类的泛型有关。

c#中带泛型的函数声明

我建议使用以下接口:

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());

(也可能有一个涉及inout方差注释的解决方案,但我对它们不是很熟悉。)

你的函数被定义为接受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