Bagaimana cara mengulang semua properti kelas?

168

Saya ada kelas.

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

Saya ingin mengulang properti dari kelas di atas. misalnya;

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

Jawaban:

297

Gunakan Refleksi:

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

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

untuk Excel - item alat / referensi apa yang harus ditambahkan untuk mendapatkan akses ke BindingFlags, karena tidak ada entri "System.Reflection" dalam daftar

Sunting: Anda juga dapat menentukan nilai BindingFlags ke type.GetProperties():

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

Itu akan membatasi properti yang dikembalikan ke properti instance publik (tidak termasuk properti statis, properti yang dilindungi, dll).

Anda tidak perlu menentukan BindingFlags.GetProperty, Anda menggunakannya saat menelepon type.InvokeMember()untuk mendapatkan nilai properti.

Brannon
sumber
Btw, bukankah seharusnya ada beberapa flag yang mengikat untuk metode GetProperties? Suka BindingFlags.Public | BindingFlags.GetPropertyatau apalah?
Svish
@Vish, Anda benar :) Ini bisa menggunakan beberapa BindingFlags, tetapi mereka opsional. Anda mungkin ingin Publik | Contoh.
Brannon
Kiat: Jika Anda berurusan dengan bidang statis, cukup lewati nol di sini: property.GetValue (null);
alansiqueira27
42

Perhatikan bahwa jika objek yang Anda bicarakan memiliki model properti khusus (seperti DataRowViewdll untuk DataTable), maka Anda perlu menggunakan TypeDescriptor; kabar baiknya adalah ini masih berfungsi dengan baik untuk kelas reguler (dan bahkan bisa lebih cepat daripada refleksi ):

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

Ini juga menyediakan akses mudah ke hal-hal seperti TypeConverteruntuk memformat:

    string fmt = prop.Converter.ConvertToString(prop.GetValue(obj));
Marc Gravell
sumber
32

Versi VB dari C # yang diberikan oleh 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

Menggunakan Binding flags sebagai ganti garis no.3

    Dim flags As BindingFlags = BindingFlags.Public Or BindingFlags.Instance
    Dim properties() As PropertyInfo = _type.GetProperties(flags)
Sachin Chavan
sumber
Terima kasih, saya akan membutuhkan waktu terlalu lama untuk mengonversi ke VB :)
Brannon
Anda selalu dapat menggunakan converter otomatis, ada banyak di web :)
balexandre
1
Ya tapi tidak semua sebaik coding tangan. Salah satu yang terkenal adalah konverter kode telerik
Sachin Chavan
Begini cara Telerik mengonversi: gist.github.com/shmup/3f5abd617a525416fee7
shmup
7

Refleksi cukup "berat"

Mungkin coba solusi ini: // 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

Refleksi memperlambat +/- 1000 x kecepatan pemanggilan metode, yang ditunjukkan dalam The Performance of Everyday Things

NicoJuicy
sumber
2

Berikut cara lain untuk melakukannya, menggunakan 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)}"))
01F0
sumber
1

Beginilah cara saya melakukannya.

foreach (var fi in typeof(CustomRoles).GetFields())
{
    var propertyName = fi.Name;
}
Chris Go
sumber
1
Gunakan GetProperties () alih-alih GetFields () jika objek / kelas mengandung properti alih-alih bidang.
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);
        }
    }

Saya menggunakan blok kode di atas untuk mengatur ulang semua properti string di objek kontrol pengguna web saya yang namanya dimulai dengan "Doc".

Mendongkrak
sumber