Saya memiliki kelas yang berisi beberapa properti (semua adalah string jika ada bedanya).
Saya juga memiliki daftar, yang berisi banyak contoh kelas yang berbeda.
Saat membuat beberapa tes unit untuk kelas saya, saya memutuskan saya ingin mengulang melalui setiap objek dalam daftar dan kemudian mengulang melalui setiap properti objek itu ...
Saya pikir melakukan ini akan sesederhana ...
foreach (Object obj in theList)
{
foreach (Property theProperties in obj)
{
do some stufff!!;
}
}
Tapi ini tidak berhasil! :( Saya mendapatkan kesalahan ini ...
"Pernyataan foreach tidak dapat beroperasi pada variabel jenis 'Application.Object' karena 'Application.Object' tidak berisi definisi publik untuk 'GetEnumerator'"
Adakah yang tahu cara melakukan ini tanpa banyak if dan loop atau tanpa masuk ke dalam sesuatu yang terlalu rumit?
c#
properties
foreach
generic-list
Jammerz858
sumber
sumber
Jawaban:
Cobalah ini:
foreach (PropertyInfo propertyInfo in obj.GetType().GetProperties()) { // do stuff here }
Juga harap dicatat bahwa
Type.GetProperties()
memiliki kelebihan beban yang menerima satu set bendera pengikat sehingga Anda dapat memfilter properti pada kriteria yang berbeda seperti tingkat aksesibilitas, lihat MSDN untuk lebih jelasnya: Type.GetProperties Method (BindingFlags) Last but not least jangan lupa untuk tambahkan referensi perakitan "system.Reflection".Misalnya untuk menyelesaikan semua properti publik:
foreach (var propertyInfo in obj.GetType() .GetProperties( BindingFlags.Public | BindingFlags.Instance)) { // do stuff here }
Tolong beri tahu saya apakah ini berfungsi seperti yang diharapkan.
sumber
Anda dapat melakukan perulangan melalui semua properti non-indeks dari sebuah objek seperti ini:
var s = new MyObject(); foreach (var p in s.GetType().GetProperties().Where(p => !p.GetGetMethod().GetParameters().Any())) { Console.WriteLine(p.GetValue(s, null)); }
Karena pengindeks
GetProperties()
mengembalikan serta properti sederhana, Anda memerlukan filter tambahan sebelum menelepon untuk mengetahui bahwa itu aman untuk diteruskanGetValue
null
sebagai parameter kedua.Anda mungkin perlu memodifikasi filter lebih lanjut untuk menyingkirkan properti hanya-tulis dan sebaliknya tidak dapat diakses.
sumber
null
getter, tetapi saya yakin OP akan mencari cara untuk mendapatkan hanya properti yang dia butuhkan.Anda hampir sampai, Anda hanya perlu mendapatkan properti dari tipe, daripada mengharapkan properti dapat diakses dalam bentuk koleksi atau tas properti:
var property in obj.GetType().GetProperties()
Dari sana Anda dapat mengakses seperti ini :
property.Name property.GetValue(obj, null)
Dengan
GetValue
parameter kedua akan memungkinkan Anda untuk menentukan nilai indeks, yang akan bekerja dengan properti yang mengembalikan koleksi - karena string adalah kumpulan karakter, Anda juga dapat menentukan indeks untuk mengembalikan karakter jika perlu.sumber
Tentu saja, tak masalah:
foreach(object item in sequence) { if (item == null) continue; foreach(PropertyInfo property in item.GetType().GetProperties()) { // do something with the property } }
sumber
if (item == null) continue;
Secara pribadi, saya pikir jika Anda mendapat objek null pada saat itu, ada yang salah jauh sebelumnya dan di situlah validasi seharusnya, atau apakah saya salah?Gunakan Refleksi untuk melakukan ini
sumber
Saya mencari jawaban untuk pertanyaan serupa di halaman ini, saya menulis jawaban untuk beberapa pertanyaan serupa yang mungkin dapat membantu orang yang masuk ke halaman ini.
Daftar Kelas
Kelas List <T> merepresentasikan daftar objek yang dapat diakses oleh indeks. Itu berada di bawah namespace System.Collection.Generic. Kelas daftar dapat digunakan untuk membuat kumpulan berbagai jenis seperti bilangan bulat, string, dll. Kelas daftar juga menyediakan metode untuk mencari, mengurutkan, dan memanipulasi daftar.
Kelas dengan properti :
class TestClss { public string id { set; get; } public string cell1 { set; get; } public string cell2 { set; get; } } var MyArray = new List<TestClss> { new TestClss() { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" }, new TestClss() { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" }, new TestClss() { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data" } }; foreach (object Item in MyArray) { Console.WriteLine("Row Start"); foreach (PropertyInfo property in Item.GetType().GetProperties()) { var Key = property.Name; var Value = property.GetValue(Item, null); Console.WriteLine("{0}={1}", Key, Value); } }
ATAU, Kelas dengan bidang :
class TestClss { public string id = ""; public string cell1 = ""; public string cell2 = ""; } var MyArray = new List<TestClss> { new TestClss() { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" }, new TestClss() { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" }, new TestClss() { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data" } }; foreach (object Item in MyArray) { Console.WriteLine("Row Start"); foreach (var fieldInfo in Item.GetType().GetFields()) { var Key = fieldInfo.Name; var Value = fieldInfo.GetValue(Item); } }
ATAU, Daftar objek (tanpa sel yang sama):
var MyArray = new List<object> { new { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" }, new { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" }, new { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data", anotherCell = "" } }; foreach (object Item in MyArray) { Console.WriteLine("Row Start"); foreach (var props in Item.GetType().GetProperties()) { var Key = props.Name; var Value = props.GetMethod.Invoke(Item, null).ToString(); Console.WriteLine("{0}={1}", Key, Value); } }
ATAU, Daftar objek (Harus memiliki sel yang sama):
var MyArray = new[] { new { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" }, new { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" }, new { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data" } }; foreach (object Item in MyArray) { Console.WriteLine("Row Start"); foreach (var props in Item.GetType().GetProperties()) { var Key = props.Name; var Value = props.GetMethod.Invoke(Item, null).ToString(); Console.WriteLine("{0}={1}", Key, Value); } }
ATAU, Daftar objek (dengan kunci):
var MyArray = new { row1 = new { id = "1", cell1 = "cell 1 row 1 Data", cell2 = "cell 2 row 1 Data" }, row2 = new { id = "2", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 2 Data" }, row3 = new { id = "3", cell1 = "cell 1 row 2 Data", cell2 = "cell 2 row 3 Data" } }; // using System.ComponentModel; for TypeDescriptor foreach (PropertyDescriptor Item in TypeDescriptor.GetProperties(MyArray)) { string Rowkey = Item.Name; object RowValue = Item.GetValue(MyArray); Console.WriteLine("Row key is: {0}", Rowkey); foreach (var props in RowValue.GetType().GetProperties()) { var Key = props.Name; var Value = props.GetMethod.Invoke(RowValue, null).ToString(); Console.WriteLine("{0}={1}", Key, Value); } }
ATAU, Daftar Kamus
var MyArray = new List<Dictionary<string, string>>() { new Dictionary<string, string>() { { "id", "1" }, { "cell1", "cell 1 row 1 Data" }, { "cell2", "cell 2 row 1 Data" } }, new Dictionary<string, string>() { { "id", "2" }, { "cell1", "cell 1 row 2 Data" }, { "cell2", "cell 2 row 2 Data" } }, new Dictionary<string, string>() { { "id", "3" }, { "cell1", "cell 1 row 3 Data" }, { "cell2", "cell 2 row 3 Data" } } }; foreach (Dictionary<string, string> Item in MyArray) { Console.WriteLine("Row Start"); foreach (KeyValuePair<string, string> props in Item) { var Key = props.Key; var Value = props.Value; Console.WriteLine("{0}={1}", Key, Value); } }
Semoga berhasil..
sumber
Sedikit peringatan, jika "melakukan beberapa hal" berarti memperbarui nilai properti sebenarnya yang Anda kunjungi DAN jika ada properti tipe struct di sepanjang jalur dari objek root ke properti yang dikunjungi, perubahan yang Anda buat pada properti tersebut akan tidak tercermin pada objek root.
sumber
Solusi salin-tempel (metode ekstensi) sebagian besar didasarkan pada tanggapan sebelumnya untuk pertanyaan ini.
Juga menangani IDicitonary (ExpandoObject / dynamic) dengan benar yang sering dibutuhkan saat menangani hal-hal yang direfleksikan ini.
Tidak disarankan untuk digunakan pada loop yang rapat dan jalur panas lainnya. Dalam kasus tersebut, Anda akan memerlukan kompilasi pohon emit / ekspresi caching / IL.
public static IEnumerable<(string Name, object Value)> GetProperties(this object src) { if (src is IDictionary<string, object> dictionary) { return dictionary.Select(x => (x.Key, x.Value)); } return src.GetObjectProperties().Select(x => (x.Name, x.GetValue(src))); } public static IEnumerable<PropertyInfo> GetObjectProperties(this object src) { return src.GetType() .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => !p.GetGetMethod().GetParameters().Any()); }
sumber
Saya tidak bisa mendapatkan salah satu cara di atas untuk bekerja, tetapi ini berhasil. Nama pengguna dan sandi untuk DirectoryEntry adalah opsional.
private List<string> getAnyDirectoryEntryPropertyValue(string userPrincipalName, string propertyToSearchFor) { List<string> returnValue = new List<string>(); try { int index = userPrincipalName.IndexOf("@"); string originatingServer = userPrincipalName.Remove(0, index + 1); string path = "LDAP://" + originatingServer; //+ @"/" + distinguishedName; DirectoryEntry objRootDSE = new DirectoryEntry(path, PSUsername, PSPassword); var objSearcher = new System.DirectoryServices.DirectorySearcher(objRootDSE); objSearcher.Filter = string.Format("(&(UserPrincipalName={0}))", userPrincipalName); SearchResultCollection properties = objSearcher.FindAll(); ResultPropertyValueCollection resPropertyCollection = properties[0].Properties[propertyToSearchFor]; foreach (string resProperty in resPropertyCollection) { returnValue.Add(resProperty); } } catch (Exception ex) { returnValue.Add(ex.Message); throw; } return returnValue; }
sumber