Bir sınıfın tüm özellikleri arasında nasıl döngü yapılır?


168

Sınıfım var.

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 döngü istiyorum. Örneğin;

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

Yanıtlar:


297

Yansıma kullanın:

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

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

Excel için - listede "System.Reflection" girişi olmadığından, BindingFlags'a erişmek için hangi araçların / referans öğelerinin eklenmesi gerekir?

Düzenleme: Ayrıca aşağıdakilere bir BindingFlags değeri belirleyebilirsiniz type.GetProperties():

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

Bu, döndürülen özellikleri genel yönetim ortamı özellikleriyle sınırlar (statik özellikler, korunan özellikler, vb. Hariç).

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


Btw, GetProperties yöntemi için bazı bağlayıcı bayraklar olmamalı mı? Beğendim BindingFlags.Public | BindingFlags.GetPropertyfalan?
Svish

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

İpucu: Statik alanlarla uğraşıyorsanız null değerini buraya iletin: property.GetValue (null);
alansiqueira27

42

Bahsettiğiniz nesnenin özel bir özellik modeli varsa ( DataRowViewvb. İçin DataTable), kullanmanız gerekir TypeDescriptor; iyi haber şu ki, bu normal sınıflar için hala iyi çalışıyor (ve yansımadan çok daha hızlı olabilir ):

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

Bu ayrıca TypeConverterbiçimlendirme gibi şeylere kolay erişim sağlar :

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

32

Brannon tarafından verilen C # 'ın VB versiyonu:

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

3 numaralı satır yerine Bağlama bayraklarını kullanma

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

Teşekkürler,
VB'ye

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

1
Evet ama hepsi el kodlaması kadar iyi değil. Dikkate değer bir kod dönüştürücü
Sachin Chavan

Telerik'in şu şekilde dönüşümü olurdu: gist.github.com/shmup/3f5abd617a525416fee7
shmup

7

Yansıma oldukça "ağır"

Belki de şu çözümü deneyin: // 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 , Günlük İşlerin Performansı bölümünde gösterilen yöntem çağrısının hızını +/- 1000 x yavaşlatır


2

LINQ lambda kullanarak bunu yapmanın başka bir yolu:

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

Ben böyle yaparım.

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

1
Nesne / sınıf alanlar yerine özellikler içeriyorsa GetFields () yerine GetProperties () kullanın.
19'da GarDavis

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

Yukarıdaki kod bloğunu "Doc" ile başlayan web kullanıcısı kontrol nesnemdeki tüm dize özelliklerini sıfırlamak için kullandım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.