我在页面上有一组用户控件,它们根据条件动态加载以运行各种报告(条件驱动程序)。每个控件都有一个或多个公开的属性,用于从我的数据库查询中获取数据。因为每个报告的控件都不同,所以我编写了一个过程来按名称访问相应控件的属性,这样我就可以将它发送到后面代码中的数据库查询(C#)。我得到了所有设置来访问这样的公共财产:
stringVal = userControl.Attributes[stringName].ToString();
它告诉我,我需要新建一个对象。我不明白我需要如何通过字符串名称动态访问该属性。在我眼前的窗口,我可以看到我想要的财产;但是,它不是control.Attributes.Count = 0
的“属性”。那么,我如何正确设置它以便我可以通过字符串名称访问它?我需要用某种东西装饰房产吗?
提前谢谢。
答案 0 :(得分:0)
你需要探索反思。它涉及操纵.NET类型(类,结构,枚举等)的元数据。但是,如果您在具有部分信任的共享主机中运行您的应用程序,则可能无法运行任何类型的反射代码(服务器上的安全限制)。如果是这种情况,请先测试一个小/快的示例(在您的托管上),然后做出相应的决定:是重新设计您的应用还是更改主机。
可能对您有用的与反射相关的代码段(将其粘贴到用户控件类中的某处,如this.GetType()
重要:
var properties = this.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
foreach (var p in properties)
{
string propertyName = p.Name;
}
还有其他方法可以获得该类型;例如typeof(yourclassname)
;您还可以反映/获取给定程序集(dll)中的所有类型,等等。
答案 1 :(得分:0)
下面,我编写了一个包装类,您可以使用它来按字符串名称设置/获取包装类的公共字段或属性。
首先,让我们看一下如何在具有公共字段或属性StartDate和SocialSecurityNumber的类上使用它。
// First create the instance we'll want to play with
MyUserControl myControlInstance = new MyUsercontrol();
// MyUserContol has two properties we'll be using
// DateTime StartDate
// int SocialSecurityNumber
// Now we're creating a map to facilitate access to the properties
// of "myControlInstance" using strings
PropertyMap<MyUserControl> map =
new PropertyMap<MyUserControl>(myControlInstance);
// Since the map is directed toward "myControlInstance"
// this line is equivalent to:
// myControlInstance.StartDate = Datetime.Now;
map.Set<DateTime>("StartDate", DateTime.Now);
// This line is equivalent to:
// ssn = myUsercontrol.SocialSecurityNumber;
int ssn = map.Get<int>("SocialSecurityNumber");
现在谈谈如何实施:
public class PropertyMap<T>
{
readonly T Instance;
public PropertyMap(T instance)
{
Instance = instance;
}
public U Get<U>(string PropertyName)
{
// Search through the type's properties for one with this name
// Properties are things with get/set accessors
PropertyInfo property = typeof(T).GetProperty(PropertyName);
if (property == null)
{
// if we couldn't find a property, look for a field.
// Fields are just member variables, but you can only
// manipulate public ones like this.
FieldInfo field = typeof(T).GetField(PropertyName);
if (field == null)
throw new Exception("Couldn't find a property/field named " + PropertyName);
return (U)field.GetValue(Instance);
}
return (U)property.GetValue(Instance, null);
}
public void Set<U>(string PropertyName, U value)
{
// Search through the type's properties for one with this name
PropertyInfo property = typeof(T).GetProperty(PropertyName);
if (property == null)
{
// if we couldn't find a property, look for a field.
FieldInfo field = typeof(T).GetField(PropertyName);
if (field == null)
throw new Exception("Couldn't find a property/field named " + PropertyName);
field.SetValue(Instance, value);
return;
}
property.SetValue(Instance, value, null);
}
}