【问题标题】:C# Generic List conversion to Class implementing List<T>C# 通用列表转换为实现 List<T> 的类
【发布时间】:2011-11-18 10:52:47
【问题描述】:

以下代码产生问题

无法将类型 'System.Collections.Generic.IEnumberable&lt;DataField&lt;string&gt;&gt;' 隐式转换为“DataFields”。存在显式转换(您是否缺少演员表?)。

我该如何解决这个问题?我做错了什么?

public class DataFields : List<DataField>
{
}

public abstract class DataField
{
    public string Name { get; set; }
}

public class DataField<T> : DataField
{
    public T Value { get; set; }
}

public static DataFields ConvertXML(XMLDocument data) {
    DataFields result = (from d in XDocument.Parse(data.OuterXML).Elements()
                      select new DataField<string>
                      {
                          Name = d.Name.ToString(),
                          Value = d.Value
                      }).ToList();
    return result;
}

已编辑:将以下信息移至另一个问题。

Using LINQ to create a List<T> where T : someClass<U>

此外,我希望能够在此语句中执行以下操作,以便为每个设置值的类型。我怎样才能做到这一点。

select new DataField<[Attribute of element called type]>
{
  Name = d.Name.ToString(),
  Value = d.Value
}

【问题讨论】:

  • 编译器如何或为什么知道使用DataFields 作为ToList() 调用的结果?为什么不选择DataFields2DataFields 的子类)或DataFields3(派生自List&lt;DataField&lt;string&gt;&gt; 的不相关类)?
  • 致所有人。好吧,显然我没有想到这一点,但它似乎应该是可能的。也许是不同的方法?我在这里不知所措,只是在寻找一些想法

标签: c# list generics linq-to-xml


【解决方案1】:

将以下构造函数添加到DataFields

public class DataFields : List<DataField> {
    public DataFields() : base() {}
    public DataFields(IEnumerable<DataField> items) : base(items){}
}  

然后

public static DataFields ConvertXML(XMLDocument data) {      
    var result = (BLAH..).ToList();      
    return new DataFields(result);     
}  

【讨论】:

  • @misha - 它适用于我,但我认为它依赖于 IEnumerable&lt;T&gt; 接口的协方差,因此仅适用于 C#4 及更高版本。
  • 在实例化新的 DataFields 之前对结果调用 Cast()
【解决方案2】:

好的,多亏了你们的一些见解,我想出了一种方法来处理这个问题

// Dont use this class
// public class DataFields : List<DataField>
// {
// }

public abstract class DataField
{
    public string Name { get; set; }
}

public class DataField<T> : DataField
{
    public T Value { get; set; }
}

public static List<DataField> ConvertXML(XMLDocument data) {  //return List<DataField>
     result = (from d in XDocument.Parse(data.OuterXML).Elements()
                      select new DataField<string>
                      {
                          Name = d.Name.ToString(),
                          Value = d.Value
                      }).Cast<DataField>().ToList();  // use cast
    return result;
}

【讨论】:

    【解决方案3】:

    正如错误所说,您正在尝试将DataField&lt;T&gt;(其中Tstring)转换为DataFields,后者继承自DatafieldList,但它们并不相同。

    所以

    DataField&lt;string&gt; 不等于 DataFields,如果你想让 DataFields : List&lt;string&gt; 工作,你可以将你的 DataFields 设为 strings 的列表

    【讨论】:

    • 我已使用反引号 (`) 将类名标记为代码序列。这一点尤其重要,因为否则泛型会被视为 html 标记,而删除泛型部分后,您的句子将没有多大意义。
    【解决方案4】:

    这个方法怎么样:

     public static DataFields ConvertXML(XmlDocument data)
            {
                DataFields result = (DataFields)(from d in XDocument.Parse(data.OuterXml).Elements()
                                      select new DataField<string>
                                      {
                                          Name = d.Name.ToString(),
                                          Value = d.Value
                                      }).Cast<DataField>();
                return result;
            }
    

    我们知道每个元素都是DataField,因此我们可以将其转换为该类型。

    【讨论】:

    • 不,这不是编译时错误。是的,它为我编译,但它不会运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多