通过反射C#调用静态类列表



我在API项目中有一系列C#静态列表,它们与这里定义的简单示例非常相似。

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",},         
};
}
}

这些模型在Javascript web应用程序和为该应用程序提供服务的API之间建立了公共信息引用。

用户正在将电子表格数据上载到API,其中包括列表类名称和列表中项目的标题。我需要能够确定与标题相关联的Id(如果有的话(。

例如,我知道该信息在列表CommonSelectOptionsYesNo.Table中,并且Title属性是";是的";。因此,我可以确定Id是1。

原则上,我可以设置一个switch/case方法,该方法选择标识为CommonSelectOptionsYesNo.Table的列表,然后获取Id值。然而,这些参考名单中有60多个,而且还在不断增加。

我可以使用反射来基于静态类对象名称调用只读静态列表的实例吗?在本例中为CommonSelectOptionsYesNo.Table?

经过进一步的研究,我们找到了以下方法来调用静态只读列表,并返回任何给定"的Id;标题";价值

propModelKey与静态列表类一起存储在所有列表的字典中。

该列表可以被提取为对象——知道该列表总是用属性名称"来声明;表";。

列表对象的属性可以根据列表的目的而变化,但它们总是具有";Id";以及";标题";属性。用简单类对象"序列化和反序列化对象;选择选项";生成一个列表,该列表可以被查询以提取与提交的标题字符串相对应的Id。

// 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; }
}

最新更新