C# Generic List conversion to Class implementing L

2020-07-20 07:40发布

问题:

The following code produces the issue

Cannot implicitly convert type 'System.Collections.Generic.IEnumberable<DataField<string>>' to 'DataFields'. An explicit conversion exists (are you missing a cast?).

How do I get around this? What am I doing wrong?

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

Edited: Moving the information below to another question.

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

In addition I would like to be able to do something like the following in this statement, in order to set the type of the value for each. How can I accomplish this.

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

回答1:

Add the following constructor to the DataFields class

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

Then

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


回答2:

OK I figured out one way to handle this thanks to some insight from you guys

// 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:

As the error says you are trying to convert DataField<T> where T is string to DataFields which inherits from List of Datafield and they are not same.

So

DataField<string> not equals DataFields, you could make your DataFields as a list of strings if you wanted this to work DataFields : List<string>



回答4:

How about this approach:

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

We know that each element is DataField so we could cast it to that type.