C#动态属性

时间:2016-04-29 19:33:33

标签: c# xml dynamic

我在此Microsoft页面上找到了此代码:Microsoft Dynamic XML Parser

 public string this[string dbName]
    {
        get
        {
            return xmlSQL.Attribute(dbName).Value;
        }
    }

我想使用这个功能,但不是像Microsoft实例中那样只返回一个对象,而是希望收到预定义的类型。

DynamicXmlParser parser = new DynamicXmlParser(@".\order.xml");
int s = parser.element;

我的intellisense和编译器知道他会得到什么。

3 个答案:

答案 0 :(得分:2)

我稍微改变了L.B's answer about DynamicXml here

public class DynamicXmlExt : DynamicObject
{
    XElement _root;
    private DynamicXmlExt(XElement root)
    {
        _root = root;
    }

    public static DynamicXmlExt Parse(string xmlString)
    {
        return new DynamicXmlExt(XDocument.Parse(xmlString).Root);
    }

    public static DynamicXmlExt Load(string filename)
    {
        return new DynamicXmlExt(XDocument.Load(filename).Root);
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = null;

        var att = _root.Attribute(binder.Name);
        if (att != null)
        {
            result = att;
            return true;
        }

        var nodes = _root.Elements(binder.Name);
        if (nodes.Count() > 1)
        {
            result = nodes.Select(n => new DynamicXmlExt(n)).ToList();
            return true;
        }

        var node = _root.Element(binder.Name);
        if (node != null)
        {
            if (node.HasElements)
            {
                result = new DynamicXmlExt(node);
            }
            else
            {
                result = node;
            }
            return true;
        }

        return true;
    }
}

现在您可以将值转换为所需类型(使用相同的xml示例):

string xml = @"<Students>
            <Student ID=""100"">
                <Name>Arul</Name>
                <Mark>90</Mark>
            </Student>
            <Student>
                <Name>Arul2</Name>
                <Mark>80</Mark>
            </Student>
        </Students>";

dynamic students = DynamicXmlExt.Parse(xml);

int id = (int)students.Student[0].ID;
int mark = (int)students.Student[0].Mark;
string name = (string)students.Student[1].Name; 

答案 1 :(得分:0)

您可以创建一个通用的getAttribute方法,该方法将使用无法始终有效的强制转换然而。特别是当输入字符串未根据正在运行的线程Thread.CurrentCulture

的区域标准进行格式化时,它将失败

您的代码可能是这样的

public T Get<T>() { return (T)xmlSQL.Attribute(dbName).Value; }

请注意,C#不支持通用索引器,因此您必须恢复使用方法

另请注意,您可能更喜欢将Nullable<T>用于值类型 - 即int?而不是int来说明没有值的情况,请参阅this link

答案 2 :(得分:0)

动态对象无法向您显示编译时运行时之前无法获知的信息(如类型你正在检索的元素)。动态点是处理编译器无法理解的对象,但开发人员可以理解其运行时属性。 Visual Studio不知道XML文档中的数据类型,因为在运行应用程序之前不会读取XML文档。

如果要以强类型方式处理XML,则应考虑XML序列化。您可以编写模拟任意XML文档的类,并使用属性控制它们的映射方式。有关详细信息,请参阅https://msdn.microsoft.com/en-us/library/2baksw0z(v=vs.110).aspx