c# eliminate switch requirement

ε祈祈猫儿з 提交于 2019-12-25 07:07:25

问题


My case value text is always be equals to the relevant OSResultStruct in the code for "The way i have it implemented now and is working".So for example if the case is osedition then the property is OSResultStruct.OSEdition.

Is it possible to do something like the line of code below? If so then i can replace my switch statement with one line of code.

lstNewItems[i].sItemValue = OSresult.OSResultStruct."lstNewItems[i].sItemName.ToString().ToUpper()";

The way i have it implimented now and is working

 switch (lstNewItems[i].sItemName)
        {
          case "osedition":
          lstNewItems[i].sItemValue = OSresult.OSResultStruct.OSEdition;
          break;
          case "osbuild":
          lstNewItems[i].sItemValue = OSresult.OSResultStruct.OSBuild;
          break;
          case "osmajor":    
          //.....

回答1:


Try Reflection:-

OSresult.OSResultStruct.GetType().GetProperty(lstNewItems[i].sItemName,BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance).GetValue(OSresult.OSResultStruct, null)

For a more generic approach:-

Define an extension class:-

public static class ClassExtensions
    {
        public static TRes GetPublicPropertyValue<T,TRes>(this T queryObject, string propertyMatch) 
            where T : class,new()
            where TRes : new()

        {
            return (TRes)typeof(T).GetProperty(propertyMatch, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance).GetValue(queryObject, null);
        }
    }

Use it for any instantiable type as follows:-

OSresult.OSResultStruct.GetPublicPropertyValue<yourtype,yourreturntype>(attribName);



回答2:


Not going to be shorter but... You may write and extension methiod and attribute. Then add that attribute to each enum member and resolved it by a string from the attribute. This will make it one line and reusable.

Some code for clarification -- as I said it was not going to be short :)

private static readonly Dictionary<DriveTrain, DriveTrainKind> DriveTrainKindMap = 
    Enums.GetValues<DriveTrain>().ToDictionary(d => d, d => d.GetDriveTrainKind());

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
public sealed class DriveTrainKindAttribute : Attribute
{
    public DriveTrainKindAttribute(DriveTrainKind kind)
    {
        Kind = kind;
    }

    public DriveTrainKind Kind { get; private set; }
}

public static class ExtensionMethods
{
    public static DriveTrainKind GetDriveTrainKind(this DriveTrain value)
    {
        var fieldInfo = typeof(DriveTrain).GetField(value.ToString());
        var attributes = fieldInfo.GetCustomAttributes(typeof(DriveTrainKindAttribute), false)
                                  .Cast<DriveTrainKindAttribute>();
        return attributes.Select(a => a.Kind).SingleOrDefault();
    }
}

public enum DriveTrainKind : byte
{
    ConventionalOrHybrid = 0,
    PluginHybrid = 1,
    BatteryElectric = 2,
}

public enum DriveTrain : short 
{
    [Description("konv_otto"), DriveTrainKind(DriveTrainKind.ConventionalOrHybrid)]
    ConventionalGasoline = 0,

    [Description("konv_diesel"), DriveTrainKind(DriveTrainKind.ConventionalOrHybrid)]
    ConventionalDiesel = 1,
    ...
}



回答3:


You can use reflection - get property accessor (Type.GetProperty ) by name (you'll need to specify IgnoreCase when getting one as your names seem to be all lower case) and than GetValue of property using accessor.



来源:https://stackoverflow.com/questions/15628140/c-sharp-eliminate-switch-requirement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!