简体   繁体   中英

Invoke a static class list by reflection C#

I have a series of C# static lists in an API project that are very similar to the simple example defined here.

using System.Collections.Generic;

namespace myproject.api.PropModels
{
  public class CommonSelectOptionsYesNoItem
  {
        public int Id { get; set; }
        public string Title { get; set; }
  }

  public static class CommonSelectOptionsYesNo
  {
    public static readonly List<CommonSelectOptionsYesNoItem> Table = new List<CommonSelectOptionsYesNoItem>
    {        
          new CommonSelectOptionsYesNoItem { Id = 0, Title = "No",},           
          new CommonSelectOptionsYesNoItem { Id = 1, Title = "Yes",},         
    };
  }
}

These models establish a common information reference between a Javascript web application and the API that services the application.

User's are uploading spreadsheet data to the API that includes the list class name and the Title of an item in the list. I need to be able to determine what Id is associated with the Title - if any.

For example I know that this the information is in the list CommonSelectOptionsYesNo.Table and the Title property is "Yes". I can therefore determine that the the Id is 1.

In principle I can set up a switch / case method that picks the list identified as CommonSelectOptionsYesNo.Table and then gets the Id value. There are however than 60 of these reference lists and they keep growing.

Can I use reflection to invoke an instance of the readonly static list based on the the static class object name - in this example CommonSelectOptionsYesNo.Table?

After further research have worked out the following method to call up the static readonly list and return the Id for any given "Title" value.

The propModelKey is stored with the static list class in a dictionary of all the lists.

The list can be extracted as an object - knowing that the list is always declared with the property name "Table".

The properties of the list objects can vary depending on the purpose of the list but they always have the "Id" and "Title" properties. Serializing and deserializing the object with the simple class object "SelectOptions" generates a list that can be queried to extract the Id corresponding to the Title string submitted.

    // This will return an Id of 1 from the simple YesNo list
    var id = GetSelectListIndex("QuestionOneId", "Yes"); 

    // Method to extract the Id of a value in a list given the list model key
    private static int? GetSelectListIndex(string propModelKey, string title)
    {
        if (SelectListModelMap.ContainsKey(propModelKey))
        {
            var model = SelectListModelMap[propModelKey];

            var typeInfo = Type.GetType("myproject.api.PropModels." + model).GetTypeInfo();

            var fieldInfo = typeInfo.DeclaredFields.FirstOrDefault(x => x.Name == "Table");

            var json = JsonConvert.SerializeObject(fieldInfo.GetValue(new object()));

            var dictionary = JsonConvert.DeserializeObject<List<SelectOptions>>(json);

            var index = dictionary.FirstOrDefault(x => x.Title == title)?.Id;

            return index;
        }

        return null;
    }

    // Dictionary of lists with model key and class name
    public static Dictionary<string, string> SelectListModelMap => new Dictionary<string, string>
    {
        { "QuestionOneId", "CommonSelectOptionsYesNo" },
        { "CountryId", "CommonSelectOptionsCountries" },
        // ... other lists
    };

    // generic class to extract the Id / Title pairs
    public class SelectOptions
    {
       public int Id { get; set; }
       public string Title { get; set; }
    }

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