2009-02-10 13 views
146

Bir dersim var.Bir sınıfın tüm özelliklerine nasıl erişilir?

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 

Yukarıdaki sınıfın özellikleri arasında geçiş yapmak istiyorum. , ör.

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

cevap

264

Kullanım Yansıma:

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

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

Düzenleme: Ayrıca type.GetProperties() bir BindingFlags değeri belirtebilirsiniz:

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

ortak örnek özelliklerine iade özelliklerini kısıtlar O (hariç statik özellikler korunan özellikler, vb.

BindingFlags.GetProperty belirtmeniz gerekmez, bir özelliğin değerini almak için type.InvokeMember() numaralı telefonu kullanırken bunu kullanırsınız.

+0

Btw, bu GetProperties yöntemi için bazı bağlayıcı bayraklar olmamalıdır? BindingFlags.Public gibi | BindingFlags.GetProperty' veya bir şey? – Svish

+0

@Svish, haklısın :) Bazı BindingFlags kullanabilir, ancak isteğe bağlıdır. Muhtemelen Kamu | Örnek. – Brannon

+0

İpucu: Statik alanlarla uğraşıyorsanız, sadece buraya null iletin: property.GetValue (null); – Seva

28

Brannon tarafından verilen C# VB sürümü:

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 

yerine

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

Teşekkürler, bu VB'ye dönüştürmek için çok uzun sürdü :) – Brannon

+0

her zaman otomatik bir dönüştürücü kullanabilirsiniz, web'de bol miktarda var :) – balexandre

+1

Evet ama hepsi el kodlama kadar iyi değil. Dikkat çekici olanı telerik kod dönüştürücüsüdür –

38

Not hat no.3 içinde Cilt bayrakları kullanarak bu bahsediyorsun nesne özel bir özellik modeli varsa (DataTable için DataRowView gibi), TypeDescriptor; İyi haber bu hala düzenli sınıflar için çalışıyor (ve hatta much quicker than reflection olabilir) olmasıdır:

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

Bu aynı zamanda biçimlendirme için TypeConverter gibi şeyler kolay erişim sağlar:

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

Yansıma güzel "

Belki de bu çözümü deneyin "ağır: // 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 

Yansıma +/- 1000 I tüm dize özelliklerini sıfırlamak kod bloğu yukarıda kullanılan The Performance of Everyday Things

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

gösterilen bir yöntem çağrısı hızını, x yavaşlar web kullanıcı kontrol nesnesinde hangi isimlerin "Doc" ile başlatıldığı.

0

İşte LINQ lambda kullanarak, bunu yapmak için başka bir yol:

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

Bu benim böyle yaparız.

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