天天看點

C#特性與反射:從XML檔案建立對象

使用C#反射,從XML檔案生成對象執行個體,以對其部分屬性指派。

1. XML檔案的格式:

<Root>
	<Test>
		<ID>1001</ID>
		<Title>Engineer</Title>
		<Salary>10000</Salary>
	</Test>
</Root>
           

2. 對象類定義:

[AttributeUsage(AttributeTargets.Property)]
    public class MyTestAttribute : Attribute
    {
    }
    
    public class Test
    {
        public Test(){}

        private string id;
        private string name;
        private string title;
        private int salary;

        public string ID
        {
            get { return id; }
            set { id = value; }
        }
        public string Title
        {
            get { return title; }
            set { title = value; }
        }
        public int Salary
        {
            get { return salary; }
            set { salary = value; }
        }

        [MyTest]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public override string ToString()
        {
            return string.Format("ID:{0}\nName:{3}\nTitle:{1}\nSalary:{2}\n", id, title, salary, string.IsNullOrEmpty(name) ? "***" : name);
        }
    }
           

3. 使用預設構造函數建立對象執行個體示例方法:

static void Main(string[] args)
        {
            CreateObj<Test>("test.xml");
            Console.ReadLine();
        }

        static void CreateObj<T>(string pathname) where T : class
        {
            Type t = typeof(T);
            XDocument doc = XDocument.Load(pathname);
            Assembly asm = Assembly.GetExecutingAssembly();
            foreach (var node in doc.Element("Root").Elements(t.Name))
            {
                object test = asm.CreateInstance(t.FullName);
                foreach (var p in t.GetProperties())
                {
                    bool mytest = false;
                    foreach (var attr in p.CustomAttributes)
                    {
                        if (attr.AttributeType == typeof(MyTestAttribute))
                        {
                            mytest = true;
                            break;
                        }
                    }
                    if (mytest) continue;
                    object obj = null;
                    switch (p.PropertyType.Name)
                    {
                        case "String":
                            obj = node.Element(p.Name).Value;
                            break;
                        case "Int32":
                            obj = int.Parse(node.Element(p.Name).Value);
                            break;
                        default: break;
                    }
                    p.SetValue(test, obj);
                }
                Console.WriteLine(test.ToString());
            }
        }