我需要访问一些东西,比如在程序执行中strClassname.strPropertyName
我将有不同的值strClassname
和名称。strProperty
请以正确的方式指导我。
在我看来,您正试图在运行时获取(或设置)对象的属性值。因此,这是执行此操作的最基本方法:
public static object GetPropertyValue(object instance, string strPropertyName)
{
Type type = instance.GetType();
System.Reflection.PropertyInfo propertyInfo = type.GetProperty(strPropertyName);
return propertyInfo.GetValue(instance, null);
}
...并设置一个值:
public static void SetPropertyValue(object instance, string strPropertyName, object newValue)
{
Type type = instance.GetType();
System.Reflection.PropertyInfo propertyInfo = type.GetProperty(strPropertyName);
propertyInfo.SetValue(instance, newValue, null);
}
如果您试图获取类的属性名称,这里有一个函数:
public static IEnumerable<string> GetPropertyNames(string className)
{
Type type = Type.GetType(className);
return type.GetProperties().Select(p => p.Name);
}
假设您有 100 个对象,并且您想要获取每个对象的 Name 属性的值,下面是一个可以执行此操作的函数:
public static IEnumerable<String> GetNames(IEnumerable<Object> objects, string nameProperty = "Name")
{
foreach (var instance in objects)
{
var type = instance.GetType();
var property = type.GetProperty(nameProperty);
yield return property.GetValue(instance, null) as string;
}
}
您可以使用反射:
要获取特定类型的属性名称,请使用方法 Type.GetProperties。方法返回 PropertyInfo 对象的数组,属性名称可通过 PropertyInfo.Name 属性获得。如果您只想获取所有属性的子集(例如仅公共静态属性),请在调用 GetProperties 方法时使用 BindingFlags。您必须至少指定两个标志,一个来自 Public/NonPublic,一个来自 Instance/Static 标志。如果使用不带 BindingFlags 参数的 GetProperties,则默认标志为 Public + NonPublic + Instance。
以下示例显示了如何获取公共静态属性。
using System.Reflection; // reflection namespace
// get all public static properties of MyClass type
PropertyInfo[] propertyInfos;
propertyInfos = typeof(MyClass).GetProperties(BindingFlags.Public |
BindingFlags.Static);
// sort properties by name
Array.Sort(propertyInfos,
delegate(PropertyInfo propertyInfo1, PropertyInfo propertyInfo2)
{ return propertyInfo1.Name.CompareTo(propertyInfo2.Name); });
// write property names
foreach (PropertyInfo propertyInfo in propertyInfos)
{
Console.WriteLine(propertyInfo.Name);
}
[来源]
如果有大约一百个类,并且您知道要访问每个类的特定属性,并且知道每个类都将被实例化,那么您绝对应该考虑创建一个包含您希望访问的属性的接口 ex。
public interface INamed
{
Name { get; }
}
示例用法:
var namedInstances = listOfClasses.Of<INamed>().Cast<INamed>();
foreach(var instance in namedInstances)
{
var name = instance.Name;
}
另一方面,如果您不打算实例化这些类,如果“名称”属性是静态或常量,则可以尝试以下方法:
public interface INamed { } //Marker interface
public static class GetNamedHelper
{
private static IEnumerable<Type> GetAssemblyTypes(IEnumerable<Assembly> assemblies)
{
if (assemblies == null) yield break;
foreach (var assembly in assemblies.Where(assembly => assembly != null))
{
IEnumerable<Type> types;
try
{
types = assembly.GetTypes().Where(t => t != null);
}
catch (ReflectionTypeLoadException rtle)
{
types = rtle.Types.Where(t => t != null);
}
foreach (var type in types)
yield return type;
}
}
private static readonly Type namedMarkerInterface = typeof (INamed);
public static IEnumerable<string> GetNames(params Assembly[] assemblies)
{
var types = GetAssemblyTypes(assemblies)
.Where(t => t.GetInterfaces().Any(intf => intf == namedMarkerInterface));
foreach (var type in types)
{
//ex. public static string Name
var prop = type.GetProperty("Name", BindingFlags.Public | BindingFlags.Static);
if (prop == null || !prop.CanRead) continue;
yield return prop.GetValue(null, null) as string;
//ex. public const string Name
var field = type.GetField("Name", BindingFlags.Public);
if (field == null || !field.IsStatic) continue;
yield return field.GetValue(null) as string;
}
}
}
无论哪种方式,您都需要知道要检查哪些类以及检查什么。