एक वर्ग के सभी गुणों के माध्यम से लूप कैसे करें?


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

एक्सेल के लिए - BindingFlags तक पहुँच प्राप्त करने के लिए क्या उपकरण / संदर्भ आइटम जोड़ा जाना चाहिए, क्योंकि सूची में कोई "System.Reflection" प्रविष्टि नहीं है

संपादित करें: आप एक BindFlags मान भी निर्दिष्ट कर सकते हैं type.GetProperties():

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

यह लौटाए गए गुणों को सार्वजनिक आवृत्ति संपत्तियों (स्थिर संपत्तियों, संरक्षित संपत्तियों को छोड़कर, आदि) तक सीमित कर देगा।

आपको निर्दिष्ट करने की आवश्यकता नहीं है BindingFlags.GetProperty, आप type.InvokeMember()किसी संपत्ति का मूल्य प्राप्त करने के लिए कॉल करते समय इसका उपयोग करते हैं।


Btw, कि getProperties विधि के लिए कुछ बाध्यकारी झंडे नहीं होना चाहिए? जैसे BindingFlags.Public | BindingFlags.GetPropertyया कुछ और?
Svish

@ सविश, आप सही हैं :) यह कुछ बाइंडिंगफ्लैग का उपयोग कर सकता है, लेकिन वे वैकल्पिक हैं। आप शायद जनता चाहते हैं | उदाहरण।
ब्रैनन

युक्ति: यदि आप स्थिर क्षेत्रों के साथ काम कर रहे हैं, तो बस यहाँ null पास करें: property.GetValue (null);
अलान्सिकिरा 27

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

Bran # द्वारा दिया गया C # का VB संस्करण:

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 में परिवर्तित होने में बहुत लंबा समय लगा होगा :)
'10

आप हमेशा एक स्वचालित कनवर्टर का उपयोग कर सकते हैं, वेब में बहुत सारे हैं :)
balexandre

1
हां लेकिन हाथ कोडिंग जितना अच्छा नहीं है। एक उल्लेखनीय टेलरेक कोड कनवर्टर है
सचिन चव्हाण

यहां बताया गया है कि कैसे टेलिक
shmup

7

परावर्तन सुंदर "भारी" है

शायद इस समाधान की कोशिश करें: // सी #

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 लैम्बडा का उपयोग करके इसे करने का एक और तरीका है:

सी#:

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
GetFields () के बजाय GetFields () का उपयोग करें यदि ऑब्जेक्ट / क्लास में फ़ील्ड्स के बजाय गुण होते हैं।
गरदिविस

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

मैंने अपने वेब उपयोगकर्ता नियंत्रण ऑब्जेक्ट में सभी स्ट्रिंग प्रॉपर्टीज़ को रीसेट करने के लिए ऊपर दिए गए कोड ब्लॉक का उपयोग किया है, जिन्हें "डॉक्टर" के साथ शुरू किया गया है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.