通过以字符串形式传递的名称引用c#对象字段
本文关键字:引用 字段 对象 字符串 | 更新日期: 2023-09-27 18:00:07
我正在C#中使用ASP.NET MVC编写一个自定义报告模块
用户将能够定义他们希望在报告中看到的字段列表。
我想知道是否可以使用字符串引用对象字段,这样我就可以枚举所选字段的列表。
例如,通常在视图中,基本上我会做以下
@foreach (Title item in Model)
{
@item.Name
@item.Isbn
}
我想找一些类似的东西
@foreach (Title item in Model)
{
@item.Select("Name")
@item.Select("Isbn")
}
实现这一点的方法之一是通过反射。在某处添加此辅助方法:
private object GetValueByPropertyName<T>(T obj, string propertyName)
{
PropertyInfo propInfo = typeof(T).GetProperty(propertyName);
return propInfo.GetValue(obj);
}
用法:
@foreach (Title item in Model)
{
var name = GetValueByPropertyName(item, "Name");
var isbn = GetValueByPropertyName(item, "Isbn");
}
好吧,我强烈建议不要在视图中使用反射,因为它打破了MVC模式的主要原则。是的,您应该使用反射,但最好在控制器中使用它。让我们来看一个简单且有效的例子。
在控制器中,我们设置了要使用的存根数据。在action方法About()中,我们获得用户选择的属性的动态列表:
class Title
{
// ctor that generates stub data
public Title()
{
Func<string> f = () => new string(Guid.NewGuid().ToString().Take(5).ToArray());
A = "A : " + f();
B = "B : " + f();
C = "C : " + f();
D = "D : " + f();
}
public string A { get; set; }
public string B { get; set; }
public string C { get; set; }
public string D { get; set; }
}
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
var data = new List<Title>()
{
new Title(), new Title(),
new Title(), new Title()
};
// list of properties to display for user
var fieldsSelectedByUser = new[] { "A", "C" };
// here we obtain a list of propertyinfos from Title class, that user requested
var propsInfo = typeof(Title).GetProperties().Where(p => fieldsSelectedByUser.Any(z => z == p.Name)).ToList();
// query that returns list of properties in List<List<object>> format
var result = data.Select(t => propsInfo.Select(pi => pi.GetValue(t, null)).ToList()).ToList();
return View(result);
}
...
}
因此,我们可以通过简单地迭代集合来使用它:
@model List<List<object>>
<br/><br />
@foreach (var list in @Model)
{
foreach (var property in list)
{
<p> @property </p>
}
<br/><br />
}
p.S.
根据MVC模式,视图应该使用控制器返回的数据,但在任何情况下都不应该在其中执行任何业务逻辑和全面的操作。如果视图需要某种格式的数据,它应该以所需的格式获得控制器返回的数据。
我对asp没有经验,所以我不确定这在您的特定环境中是否可行。
但通常情况下,你可以通过反思来做到这一点。但你必须知道你是在寻找属性还是字段
对于字段:
FieldInfo fi = item.GetType().GetField("Name", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
var value = fi.GetValue(item); // read a field
fi.SetValue(item, value); // set a field
属性:
PropertyInfo pi = item.GetType().GetProperty("Name", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
var value = pi.GetValue(item); // read a property
pi.SetValue(item, value); // set a property
谷歌搜索的单词是"Reflection",大多数方法都可以在Type
类中找到。