Come passare in rassegna tutte le proprietà di una class?

Ho una lezione.

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 

Voglio scorrere le proprietà della class precedente. per esempio;

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

Usa la riflessione:

 Type type = obj.GetType(); PropertyInfo[] properties = type.GetProperties(); foreach (PropertyInfo property in properties) { Console.WriteLine("Name: " + property.Name + ", Value: " + property.GetValue(obj, null)); } 

Modifica: puoi anche specificare un valore BindingFlags per type.GetProperties() :

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

Ciò limiterà le proprietà restituite alle proprietà di istanza pubbliche (escluse proprietà statiche, proprietà protette, ecc.).

Non è necessario specificare BindingFlags.GetProperty , lo si utilizza quando si chiama type.InvokeMember() per ottenere il valore di una proprietà.

Si noti che se l’object di cui si sta parlando ha un modello di proprietà personalizzato (come DataRowView ecc per DataTable ), è necessario utilizzare TypeDescriptor ; la buona notizia è che funziona ancora bene per le classi regolari (e può anche essere molto più veloce della riflessione ):

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

Questo fornisce anche un facile accesso a cose come TypeConverter per la formattazione:

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

Versione VB di C # fornita da Brannon:

 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 

Utilizzare i flag di binding in invece della riga n

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

La riflessione è piuttosto “pesante”

Forse prova questa soluzione: // 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 

La riflessione rallenta di +/- 1000 volte la velocità di una chiamata al metodo, mostrata in The Performance of Everyday Things

 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); } } 

Ho usato il blocco di codice qui sopra per ripristinare tutte le proprietà della stringa nel mio object di controllo utente web, i cui nomi sono iniziati con “Doc”.

Ecco un altro modo per farlo, usando un lambda LINQ:

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)}")) 

Questo è come lo faccio.

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