如何循环遍历一个类的所有属性?

我还有课。

Public Class Foo
Private _Name As String
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property


Private _Age As String
Public Property Age() As String
Get
Return _Age
End Get
Set(ByVal value As String)
_Age = value
End Set
End Property


Private _ContactNumber As String
Public Property ContactNumber() As String
Get
Return _ContactNumber
End Get
Set(ByVal value As String)
_ContactNumber = value
End Set
End Property




End Class

我想循环遍历上面类的属性。 例如:

Public Sub DisplayAll(ByVal Someobject As Foo)
For Each _Property As something In Someobject.Properties
Console.WriteLine(_Property.Name & "=" & _Property.value)
Next
End Sub
162145 次浏览

使用反思:

Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties();


foreach (PropertyInfo property in properties)
{
Console.WriteLine("Name: " + property.Name + ", Value: " + property.GetValue(obj, null));
}

对于 Excel-必须添加哪些工具/引用项才能访问 BindingFlags,因为没有“ System”。列表中的“反射”项

编辑: 还可以将 BindingFlags 值指定为 type.GetProperties():

BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
PropertyInfo[] properties = type.GetProperties(flags);

将返回的属性限制为公共实例属性(不包括静态属性、受保护属性等)。

您不需要指定 BindingFlags.GetProperty,您可以在调用 type.InvokeMember()时使用它来获取属性的值。

由 Brannon 提供的 C # 的 VB 版本:

Public Sub DisplayAll(ByVal Someobject As Foo)
Dim _type As Type = Someobject.GetType()
Dim properties() As PropertyInfo = _type.GetProperties()  'line 3
For Each _property As PropertyInfo In properties
Console.WriteLine("Name: " + _property.Name + ", Value: " + _property.GetValue(Someobject, Nothing))
Next
End Sub

使用 Binding 标志代替第3行

    Dim flags As BindingFlags = BindingFlags.Public Or BindingFlags.Instance
Dim properties() As PropertyInfo = _type.GetProperties(flags)

注意,如果你谈论的对象有一个自定义属性模型(比如 DataRowViewDataTable) ,那么你需要使用 TypeDescriptor; 好消息是,这仍然可以很好地用于常规类(甚至可以是 比反射要快得多) :

foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(obj)) {
Console.WriteLine("{0} = {1}", prop.Name, prop.GetValue(obj));
}

这还提供了对 TypeConverter等格式化内容的简单访问:

    string fmt = prop.Converter.ConvertToString(prop.GetValue(obj));

反射相当“沉重”

也许可以试试这个办法:

C #

if (item is IEnumerable) {
foreach (object o in item as IEnumerable) {
//do function
}
} else {
foreach (System.Reflection.PropertyInfo p in obj.GetType().GetProperties())      {
if (p.CanRead) {
Console.WriteLine("{0}: {1}", p.Name, p.GetValue(obj,  null)); //possible function
}
}
}

VB.Net

  If TypeOf item Is IEnumerable Then


For Each o As Object In TryCast(item, IEnumerable)
'Do Function
Next
Else
For Each p As System.Reflection.PropertyInfo In obj.GetType().GetProperties()
If p.CanRead Then
Console.WriteLine("{0}: {1}", p.Name, p.GetValue(obj, Nothing))  'possible function
End If
Next
End If

反射减慢 +/-1000倍于方法调用的速度,如 日常事物的表现所示

private void ResetAllProperties()
{
Type type = this.GetType();
PropertyInfo[] properties = (from c in type.GetProperties()
where c.Name.StartsWith("Doc")
select c).ToArray();
foreach (PropertyInfo item in properties)
{
if (item.PropertyType.FullName == "System.String")
item.SetValue(this, "", null);
}
}

我使用上面的代码块来重置我的 web 用户控件对象中名称以“ Doc”开头的所有字符串属性。

下面是另一种方法,使用 LINQ lambda:

C # :

SomeObject.GetType().GetProperties().ToList().ForEach(x => Console.WriteLine($"{x.Name} = {x.GetValue(SomeObject, null)}"));

VB.NET:

SomeObject.GetType.GetProperties.ToList.ForEach(Sub(x) Console.WriteLine($"{x.Name} = {x.GetValue(SomeObject, Nothing)}"))

我就是这么做的。

foreach (var fi in typeof(CustomRoles).GetFields())
{
var propertyName = fi.Name;
}

我使用这个示例将数据序列化到自定义文件(ini 和 xml 混合)中


' **Example of class test :**


Imports System.Reflection
Imports System.Text


Public Class Player
Property Name As String
Property Strong As Double
Property Life As Integer
Property Mana As Integer
Property PlayerItems As List(Of PlayerItem)
    

Sub New()
Me.PlayerItems = New List(Of PlayerItem)
End Sub
    

Class PlayerItem
Property Name As String
Property ItemType As String
Property ItemValue As Integer
    

Sub New(name As String, itemtype As String, itemvalue As Integer)
Me.Name = name
Me.ItemType = itemtype
Me.ItemValue = itemvalue
End Sub
End Class
End Class
    

' **Loop function of properties**


Sub ImportClass(varobject As Object)
Dim MaVarGeneric As Object = varobject
Dim MaVarType As Type = MaVarGeneric.GetType
Dim MaVarProps As PropertyInfo() = MaVarType.GetProperties(BindingFlags.Public Or BindingFlags.Instance)


Console.Write("Extract " & MaVarProps.Count & " propertie(s) from ")
If MaVarType.DeclaringType IsNot Nothing Then
Console.WriteLine(MaVarType.DeclaringType.ToString & "." & MaVarType.Name)
Else
Console.WriteLine(MaVarType.Namespace & "." & MaVarType.Name)
End If


For Each prop As PropertyInfo In MaVarProps
If prop.CanRead = True Then


If prop.GetIndexParameters().Length = 0 Then
Dim MaVarValue As Object = prop.GetValue(MaVarGeneric)
Dim MaVarValueType As Type = MaVarValue.GetType


If MaVarValueType.Name.Contains("List") = True Then
Dim MaVarArguments As New StringBuilder
For Each GenericParamType As Type In prop.PropertyType.GenericTypeArguments
If MaVarArguments.Length = 0 Then
MaVarArguments.Append(GenericParamType.Name)
Else
MaVarArguments.Append(", " & GenericParamType.Name)
End If
Next
Console.WriteLine("Sub-Extract: " & prop.MemberType.ToString & " " & prop.Name & " As List(Of " & MaVarArguments.ToString & ")")
Dim idxItem As Integer = 0
For Each ListItem As Object In MaVarValue
Call ImportClass(MaVarValue(idxItem))
idxItem += 1
Next
Continue For
Else
Console.WriteLine(prop.MemberType.ToString & " " & prop.Name & " As " & MaVarValueType.Name & " = " & prop.GetValue(varobject))
End If


End If
End If
Next
End Sub


' **To test it :**


Dim newplayer As New Player With {
.Name = "Clark Kent",
.Strong = 5.5,
.Life = 100,
.Mana = 50
}
' Grab a chest
newplayer.PlayerItems.Add(New Player.PlayerItem("Chest", "Gold", 5000))
' Grab a potion
newplayer.PlayerItems.Add(New Player.PlayerItem("Potion", "Life", 50))
' Extraction & Console output
Call ImportClass(newplayer)

The preview in Console : Result of the properties loop of a class