如何将通用类型的项添加到列表中?

时间:2016-11-14 21:25:34

标签: c# asp.net

应该相对简单,但我无法弄清楚,我有以下几点:

  public static List<T> GetList <T>(dynamic data)
    {
        var lst = new List<T>();

        foreach (var d in data)
        {
            lst.Add(new T { Value = d.Id.ToString(), Text = d.Name };);
        }

        return lst;
    }

errror:

enter image description here

3 个答案:

答案 0 :(得分:7)

您将类型约束为T但未对该类型提供其他约束。编译器无法知道存在属性Value或Text。您可以使用接口然后约束该类型。调用方法时传入的类型也必须实现该接口。

public interface ITextValue{
   string Text {get;set;}
   string Value {get;set;}
}

然后添加约束的代码

public static List<T> GetList <T>(dynamic data) where T : ITextValue, new()
{
    var lst = new List<T>();

    foreach (var d in data)
    {
        lst.Add(new T { Value = d.Id.ToString(), Text = d.Name });
    }

    return lst;
}

这是关于可应用于泛型类型参数的那些约束的所有可用约束和语法的良好链接。 Constraints on Type Parameters (C# Programming Guide)。除了@juan指出的new()约束指定您使用的类型必须具有无参数构造函数。

答案 1 :(得分:1)

使用C#泛型,您只能在泛型类型参数的实例上执行这些操作,这些参数对于编译器已知的任何类型都存在,这些类型符合相应泛型类型或泛型方法指定的泛型类型约束。换句话说,在您的特定情况下,编译器有两个问题。

首先,您尝试构造T的实例,但并非每种类型都可以像这样构造(例如,委托不能)。此外,并非每个可构造类型都是 default-constructible (换句话说,它具有默认构造函数)。为了能够像这样构造类型为T的实例,您需要要求T使用默认构造函数在T上应用 new()约束。

其次,为了能够在新构造的T实例上初始化属性文本,您需要确保类型T指定了这些属性和这些属性是公开可设置,通常是通过强制执行T来实现某个界面。

以下是您可能希望在代码中执行的操作的一个小示例。

interface IHasStringValueAndText {
    String Value { get; set; }
    String Text { get; set; }
}

public static List<T> GetList<T>(dynamic data) where T : IHasStringValueAndText, new() {
    var lst = new List<T>();

    foreach (var d in data) {
        lst.Add(new T { Value = d.Id.ToString(), Text = d.Name });
    }

    return lst;
}

请注意,如果您确实不需要约束来处理您的特定情况,那么它可能对您的进一步工作有用。

答案 2 :(得分:0)

您需要约束一个包含Value和Text作为属性的类,否则它将无法找到这些属性。例如:

其中TypeName是包含值和文本的类型。

<div class="big back"></div>
<div class="small back"></div>
<div class="big front"></div>
<div class="small front"></div>