使用LINQ to创建一个列表< T>其中T:SomeClass的< U> [英] Using LINQ to create a List<T> where T : someClass<U>

查看:84
本文介绍了使用LINQ to创建一个列表< T>其中T:SomeClass的< U>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是关系到我的 C#泛型的问题之前,列表转换为类实现列表< T>

我有以下代码:

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) {  
     result = (from d in XDocument.Parse(data.OuterXML).Root.Decendendants()
                      select new DataField<string>
                      {
                          Name = d.Name.ToString(),
                          Value = d.Value
                      }).Cast<DataField>().ToList();  
    return result;
}

这工作,但是我希望能够修改的选择部分LINQ查询是这样的:

This works however I would like to be able to modify the select portion of the LINQ query to be something like this:

select new DataField<[type defined in attribute of XML Element]>
{
  Name = d.Name.ToString(),
  Value = d.Value
}

这是只是一个可怜的方法吗?是否可以?任何建议

Is this just a poor approach? is it possible? Any suggestions?

推荐答案

下面是一个有效的解决方案:(你必须指定你的类型的属性完全限定的类型名称否则,您必须配置映射莫名其妙......)

Here is a working solution: (You must specify fully qualified type names for your Type attribute otherwise you have to configure a mapping somehow...)

我用的是动态的关键字,你可以使用反射来设置值,而不是如果你没有C#4你...

I used the dynamic keyword, you can use reflection to set the value instead if you do not have C# 4...

public static void Test()
{
    string xmlData = "<root><Name1 Type=\"System.String\">Value1</Name1><Name2 Type=\"System.Int32\">324</Name2></root>";

    List<DataField> dataFieldList = DataField.ConvertXML(xmlData);

    Debug.Assert(dataFieldList.Count == 2);
    Debug.Assert(dataFieldList[0].GetType() == typeof(DataField<string>));
    Debug.Assert(dataFieldList[1].GetType() == typeof(DataField<int>));
}

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

    /// <summary>
    /// Instanciate a generic DataField<T> given an XElement
    /// </summary>
    public static DataField CreateDataField(XElement element)
    {
        //Determine the type of element we deal with
        string elementTypeName = element.Attribute("Type").Value;
        Type elementType = Type.GetType(elementTypeName);

        //Instanciate a new Generic element of type: DataField<T>
        dynamic dataField = Activator.CreateInstance(typeof(DataField<>).MakeGenericType(elementType));
        dataField.Name = element.Name.ToString();

        //Convert the inner value to the target element type
        dynamic value = Convert.ChangeType(element.Value, elementType);

        //Set the value into DataField
        dataField.Value = value;

        return dataField;
    }

    /// <summary>
    /// Take all the descendant of the root node and creates a DataField for each
    /// </summary>
    public static List<DataField> ConvertXML(string xmlData)
    {
        var result = (from d in XDocument.Parse(xmlData).Root.DescendantNodes().OfType<XElement>()
                      select CreateDataField(d)).ToList();

        return result;
    }
}

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

这篇关于使用LINQ to创建一个列表&LT; T&GT;其中T:SomeClass的&LT; U&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆