C#泛型列表转换为实现List<T>的类

3
以下代码产生了问题:

无法隐式地将类型 'System.Collections.Generic.IEnumberable<DataField<string>>' 转换为 '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;
}

编辑:将以下信息移动到另一个问题中。

使用LINQ创建一个List<T>,其中T:someClass<U>

此外,我想在这个语句中做一些类似下面的事情,以便为每个值设置类型。我该如何实现呢?

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

编译器如何或为什么会知道在 ToList() 调用的结果中使用 DataFields?为什么它不会选择 DataFields2DataFields 的子类)或 DataFields3(从 List<DataField<string>> 派生的不相关类)? - Damien_The_Unbeliever
大家好。好吧,显然我没有仔细考虑过这个问题,但似乎应该是可行的。也许可以尝试一种不同的方法?我在这里有些困惑,只是希望能得到一些想法。 - John Hartsock
4个回答

5
将以下构造函数添加到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);     
}  

1
@misha - 对我来说它有效,但我认为它依赖于IEnumerable<T>接口的协变性,因此仅适用于C#4及更高版本。 - Damien_The_Unbeliever
在实例化新的DataFields之前,只需在结果上调用Cast<DataField>()即可。 - cwharris

1

好的,我找到了一种处理方法,感谢你们的启示。

// 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;
}

0
根据错误提示,您正在尝试将泛型 DataField<T> (其中Tstring)转换为继承自ListDataFields 类型,它们不相同。
因此, DataField<string> 不等于 DataFields,如果您希望使其工作,可以将 DataFields 做成一个字符串列表 DataFields : List<string>

我已经使用反引号(`)将类名标记为代码序列。这一点尤其重要,因为否则泛型会被视为HTML标签,当泛型部分被删除时,您的句子就没有多少意义了。 - Damien_The_Unbeliever

0
这个方法怎么样?
 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,因此我们可以将其转换为该类型。


不,这不是编译时错误。是的,它对我来说可以编译,但无法运行。 - John Hartsock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接