Як переглядати всі властивості класу?


168

У мене клас.

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

Відповіді:


297

Використовуйте відображення:

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.Reflection"

Редагувати: Ви також можете вказати значення BindingFlags для type.GetProperties():

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

Це обмежить повернені властивості властивостями публічного екземпляра (виключаючи статичні властивості, захищені властивості тощо).

Не потрібно вказувати BindingFlags.GetProperty, ви використовуєте це під час дзвінка, type.InvokeMember()щоб отримати вартість властивості.


Btw, чи не повинні бути якісь прапори прив'язки для цього методу GetProperties? Як, BindingFlags.Public | BindingFlags.GetPropertyчи щось?
Свиш

@Svish, ти маєш рацію :) Він може використовувати деякі BindingFlags, але вони необов'язкові. Ви, мабуть, хочете, щоб громадськість | Екземпляр.
Браннон

Порада: Якщо ви маєте справу зі статичними полями, просто пропустіть тут null: property.GetValue (null);
alansiqueira27

42

Зауважте, що якщо об’єкт, про який ви говорите, має власну модель властивості (наприклад, DataRowViewтощо для DataTable), тоді вам потрібно скористатися 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));

32

VB версія C #, надана Бранноном:

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

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

Дякую, мені знадобилося б занадто багато часу, щоб перетворитись на VB :)
Браннон,

Ви завжди можете скористатися автоматичним перетворювачем, в Інтернеті їх є багато :)
balexandre

1
Так, але не все так добре, як кодування вручну. Одним із відомих є перетворювач коду telerik
Sachin Chavan

Ось як Telerik перетворив би: gist.github.com/shmup/3f5abd617a525416fee7
shmup

7

Рефлексія досить "важка"

Можливо, спробуйте це рішення: // 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 x швидкість виклику методу, показану в «Продуктивність щоденних речей»


2

Ось ще один спосіб зробити це, використовуючи лямбда 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)}"))

1

Ось як я це роблю.

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

1
Використовуйте GetProperties () замість GetFields (), якщо об'єкт / клас містить властивості замість полів.
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);
        }
    }

Я використав вищевказаний блок коду для скидання всіх властивостей рядка в моєму об'єкті управління веб-користувачем, імена якого починаються з "Doc".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.