简体   繁体   中英

assigning property type at runtime in C#

I have class in which childNodeValue can be string or List<ChildAttribute> same class, if same class not supported then another class with same properties, while looping through I need to assign required type to childNodeValue .

public class ChildAttribute
{
    public int? sequence { get; set; }
    public  Type<T> childNodeValue { get; set; } // string or List<ChildAttribute>
    public int? parentId { get; set; }

}

How do assign type at runtime in my bellow code;

foreach (var pItem in pNodes)
{
    ParentAttribute pAtt = new ParentAttribute();
    pAtt.parentNodeValue = pItem["Attribute"].ToString();
    pAtt.id = Convert.ToInt32(pItem["ID"]);

    pAtt.ChildNodeValues = new List<ChildAttribute>();

    var cNodes = (from cRow in dt.AsEnumerable()
                  where cRow.Field<decimal?>("Parent_Id") == pAtt.id
                  select cRow).ToList();


    foreach (var cItem in cNodes)
    {
        ChildAttribute cAtt = new ChildAttribute();
        // May be another foreach required here 
        cAtt.childNodeValue = cItem["Attribute"].ToString();
        cAtt.sequence = Convert.ToInt32(!cItem.IsNull("Sequence"));
        cAtt.parentId = Convert.ToInt32(!cItem.IsNull("Parent_Id"));

        pAtt.ChildNodeValues.Add(cAtt);
    }
    att.ParentNodes.Add(pAtt);
}  

In C#, you have a few options:

  1. Declare your property as object .
  2. Declare your property as dynamic .
  3. Use two properties with different names, one with type string and another with type List .
  4. Define a new class ChildrenOrValue that holds two properties. Implement an implicit type conversion to and from both string and List .

The downside of options 1 and 2 is that you'd have to check for the actual run-time type every time you try to access this property and cast those values back to the appropriate type before each use. The 4th option this is the most complex and is probably an overkill.

The third option makes the most sense:

public class ChildAttribute
{
    public int? sequence { get; set; }
    public List<ChildAttribute> children { get; set; }
    public string value { get; set; }
    public int? parentId { get; set; }
}

Even though this option forces you to check which property is available every time you want to use those, it doesn't require you to downcast to the appropriate type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM