有没有一种简单的方法可以从 C# 中不同类型的 child class 属性的字符串中通用解析数据?

Is there a simple way to generically parse data from strings for child class properties of differing types in C#?

我有基地class

abstract public class containerClass {
    protected containerClass () {
        // do stuff
    }

    virtual protected void parseData() {
        // do the stuff I'm mentioning later
    }
}

和child classes

public class childClassOne : containerClass {
    public childClassOne () : base () {
        var1S = "99";
        var2S = "88.3";
        var3S = "2015-04-22T15:55:25.2625065-07:00";
    }
    public int var1 {get; protected set;}
    public double var2 {get; protected set;}
    public DateTime var3 {get; protected set;}

    public string var1S {get; protected set;}
    public string var2S {get; protected set;}
    public string var3S {get; protected set;}
}

public class childClassTwo : containerClass {
    public childClassTwo () : base () {
        var1S = "99.22";
        var2S = "88.3";
        var3S = "43.44";
    }
    public double var1 {get; protected set;}
    public double var2 {get; protected set;}
    public double var3 {get; protected set;}

    public string var1S {get; protected set;}
    public string var2S {get; protected set;}
    public string var3S {get; protected set;}
}

我想做的是在 parent class 中定义 parseData 以在 child class 调用时遍历属性并解析字符串相关数据。

需要保留顺序。并且字符串可能是外部数据,而不是这些 classes.

的属性或字段

我目前在pseudo-code的想法是这样的:

for (property prop in thisClass)
{
    typeof(prop) temp;
    if (typeof(prop).tryParse(var1S, temp))
        prop = temp;
}

我正在查看的所有 class 都有一个带有两个输入变量的 tryParse 方法。我正在尝试做的事情可以工作吗?如果是这样,我如何以明确的顺序遍历属性?

简单?没有。可能吗?是的。

What I want to do is define parseData in the parent class to iterate through the properties when it's called by a child class and parse the strings for relevant data.

下面是你问题的第一部分。 Here is a fiddle to demonstrate.

virtual protected void parseData()
{
    // iterate through the properties when it's called by a child class
    foreach(var p in this.GetType().GetProperties())
    {
        // and parse the strings for relevant data
        var propName = p.Name;
        var propValue = p.GetValue(this);
        Console.WriteLine(string.Format("{0} = {1}", propName, propValue));
    }
}

Order needs to be preserved.

这里就不简单了。 MSDN says that、"The order of the returned collection is not guaranteed to be identical between calls."

这个问题`Type.GetProperties` property order有一个答案推荐一个自定义属性来保存顺序。可能看起来像这样:

[System.AttributeUsage(System.AttributeTargets.Property)]
public class ProperyOrderAttribute : System.Attribute
{
    public int Order { get; private set; }

    public ProperyOrderAttribute(int order)
    {
        this.Order = order;
    }
}

您可以在您的资产中像这样使用它。

[ProperyOrderAttribute(0)]
public int var1 { get; protected set; }

你会 compare 像这样:

protected Comparison<PropertyInfo> comparer = (x,y) => {
    var type = typeof(ProperyOrderAttribute);
    var xAttr = x.GetCustomAttributes(type, false);
    var yAttr = y.GetCustomAttributes(type, false);
    var xOrder = xAttr.Count() > 0 ? 
        (xAttr[0] as ProperyOrderAttribute).Order : 
        Int64.MaxValue;
    var yOrder = yAttr.Count() > 0 ? 
        (yAttr[0] as ProperyOrderAttribute).Order : 
        Int64.MaxValue;
    return xOrder.CompareTo(yOrder);
};

这就是保留顺序的最终 parseData() 方法的工作方式:

virtual protected void parseData()
{
    var properties = this.GetType().GetProperties();

    // maintain the order
    Array.Sort(properties, comparer);

    // iterate through the properties when it's called by a child class
    foreach (var p in properties)
    {
        // and parse the strings for relevant data
        var propName = p.Name;
        var propValue = p.GetValue(this);
        Console.WriteLine(string.Format("{0} = {1}", propName, propValue));
    }
}

同样,this fiddle demonstrates the complete solution