我想知道类的所有属性的名称,只给出类名。 看起来应该是这样的:
public object GetClassAttribute(string className)
鉴于这两个类:
public class PersonItem
{
public string Name {get;set;}
public string LastName {get;set;}
public byte Age {get;set;}
}
public class DepartmentItem
{
public string DepartmentName {get;set;}
public string Office {get;set;}
public string Address {get;set;}
}
该功能应该是这样的:
var ListAttribute= GetClassAttribute(Person);
// returns:
// ListAttribute[0] "Name"
// ListAttribute[1] "LastName"
// ListAttribute[2] "Age
var ListAttribute= GetClassAttribute(DepartmentItem);
// returns:
// ListAttribute[0] "DepartmentName "
// ListAttribute[1] "Office "
// ListAttribute[2] "Address
答案 0 :(得分:3)
我想你想反思一种类型。你问的问题可以像这样查询:
public static IEnumerable<string> FieldsOf(string className)
{
var asm = Assembly.GetCallingAssembly();
var type = asm.GetTypes().Single(t => t.Name == className);
var fields = type.GetFields();
return fields.Select(f => f.Name);
}
此函数首先获取它的调用程序集,然后搜索具有给定名称的唯一类 - 您必须这样做,因为通常使用Assembly.GetType(fullName)
按名称搜索全名(包括它的名称空间),但示例你给了没有。
如果您有多个具有相同名称的类(例如,不同的名称空间),则可能会失败!
最后它获取所有字段并返回其名称。
这也找不到属性! (您必须使用GetProperties
搜索它们,并且您可能希望控制字段的找到方式 - 例如没有私有等等。所有这些都可以通过检查字段属性或提供更多参数来控制到GetFields
。
顺便说一下:你的班级定义也是错误的 - 每行后都有;
个缺失:
public class PersonItem
{
public string Name;
public string LastName;
public byte Age;
}
您可以打印它的字段:
foreach (var f in FieldsOf("PersonItem"))
Console.WriteLine(f);
我想迟早你也需要这些值 - 这里是上述方法的扩展,展示了你如何做到这一点:
public static IEnumerable<Tuple<string, Func<object, object>>> FieldsOf(string className)
{
var asm = Assembly.GetCallingAssembly();
var type = asm.GetTypes().Single(t => t.Name == className);
var fields = type.GetFields();
return fields.Select(f => Tuple.Create<string, Func<object, object>>(f.Name, f.GetValue));
}
这个返回元组中字段的Name
和Getter
(对于这个例子来说足够了 - 通常你应该使用一个结构或名称比Item1
更好的东西和{ {1}}关于它的属性)。
以下是一个例子:
Item2
这将提供此输出:
Object person = new PersonItem {Name = "John", LastName = "Smith", Age = 33};
foreach (var f in FieldsOf("PersonItem"))
Console.WriteLine("Fieldname: {0} - Value: {1}", f.Item1, f.Item2(person));
由于您现在更改了问题,以便您使用的类只有属性(而不是字段) - 您还需要包含这些:
Fieldname: Name - Value: John
Fieldname: LastName - Value: Smith
Fieldname: Age - Value: 33
注意:此代码只会获取不使用索引的属性(如您所述) - 这是部分public static IEnumerable<Tuple<string, Func<object, object>>> FieldsOf(string className)
{
var asm = Assembly.GetCallingAssembly();
var type = asm.GetTypes().Single(t => t.Name == className);
var fields = type.GetFields();
var properties = type.GetProperties();
return
fields.Select(f => Tuple.Create<string, Func<object, object>>(f.Name, f.GetValue))
.Concat(properties.Select(p => Tuple.Create<string, Func<object, object>>(p.Name, o => p.GetValue(o, null))));
}
- o => p.GetValue(o, null)
是索引所需的位置如果你也需要那些。
null
代替type-name Amir提出了一个很好的观点:你也可以使用这些类型。
如果您在编译时不知道对象类型,那么这个很好:
Type
示例:
public static IEnumerable<Tuple<string, Func<object, object>>> FieldsOf(Type type)
{
var fields = type.GetFields();
var properties = type.GetProperties();
return
fields.Select(f => Tuple.Create<string, Func<object, object>>(f.Name, f.GetValue))
.Concat(properties.Select(p => Tuple.Create<string, Func<object, object>>(p.Name, o => p.GetValue(o, null))));
}
这是一个通用版本 - 如果您在编译时知道类型,那么这个版本很好:
Object person = new PersonItem {Name = "John", LastName = "Smith", Age = 33};
foreach (var f in FieldsOf(person.GetType()))
Console.WriteLine("Fieldname: {0} - Value: {1}", f.Item1, f.Item2(person));
Console.ReadLine();
示例:
public static IEnumerable<Tuple<string, Func<T, object>>> FieldsOf<T>()
{
var type = typeof (T);
var fields = type.GetFields();
var properties = type.GetProperties();
return
fields.Select(f => Tuple.Create<string, Func<T, object>>(f.Name, o => f.GetValue(o)))
.Concat(properties.Select(p => Tuple.Create<string, Func<T, object>>(p.Name, o => p.GetValue((T)o, null))));
}
答案 1 :(得分:1)
上面的两个答案很棒,但是你问了一个特定的属性问题,所以这里是一个&#34;复制粘贴&#34;回答:
public IEnumerable<string> GetPropertyNames(Type type)
{
return type.GetProperties().Select(p => p.Name);
}
用法:
var personItemProps = GetPropertyNames(typeof(PersonItem)).ToList();
var departmentItemProps = GetPropertyNames(typeof(DepartmentItem)).ToList();
您也可以使用&#34; Type&#34;:
上的扩展功能执行此操作 public static class TypeExtensions
{
public static IEnumerable<string> GetPropertyNames(this Type type)
{
return type.GetProperties().Select(p => p.Name);
}
}
用法:
var personItemProps = typeof(PersonItem).GetPropertyNames().ToList();
var departmentItemProps = typeof(DepartmentItem).GetPropertyNames().ToList();
如果您不需要IEnumerables,那么只需更改函数以返回List。
答案 2 :(得分:0)
您可以从类名(字符串)获取属性列表,首先使用Type.GetType将字符串转换为Type。获得类型后,可以调用GetFields()来获取属性。
方法定义
public IEnumerable<string> GetClassAttribute(string className)
{
Type t = Type.GetType(className);
return t.GetFields().Select(f=>f.Name);
}
方法调用
var attributes = GetClassAttribute("ClassNamespace.PersonItem");
注意您需要按照MSDN文档中的说明为您的类提供命名空间。
typeName类型:System.String类型的程序集限定名称 要得到。请参阅AssemblyQualifiedName。如果类型在当前 执行程序集或在Mscorlib.dll中,它足以提供 类型名称由其命名空间限定。