(Lihat solusi di bawah ini yang saya buat menggunakan jawaban yang saya terima)
Saya mencoba untuk meningkatkan pemeliharaan dari beberapa kode yang melibatkan refleksi. Aplikasi ini memiliki antarmuka .NET Remoting mengekspos (antara lain) metode yang disebut Jalankan untuk mengakses bagian-bagian dari aplikasi yang tidak termasuk dalam antarmuka jarak jauh yang diterbitkan.
Berikut adalah cara aplikasi menentukan properti (yang statis dalam contoh ini) yang dimaksudkan agar dapat diakses melalui Execute:
RemoteMgr.ExposeProperty("SomeSecret", typeof(SomeClass), "SomeProperty");
Jadi pengguna jarak jauh dapat menelepon:
string response = remoteObject.Execute("SomeSecret");
dan aplikasi akan menggunakan refleksi untuk menemukan SomeClass.SomeProperty dan mengembalikan nilainya sebagai string.
Sayangnya, jika seseorang mengganti nama SomeProperty dan lupa untuk mengubah parm ke-3 dari ExposeProperty (), ia merusak mekanisme ini.
Saya perlu yang setara dengan:
SomeClass.SomeProperty.GetTheNameOfThisPropertyAsAString()
untuk digunakan sebagai parm ke-3 di ExposeProperty sehingga alat refactoring akan menangani penggantian nama.
Apakah ada cara untuk melakukan ini? Terima kasih sebelumnya.
Oke, inilah yang akhirnya saya buat (berdasarkan jawaban yang saya pilih dan pertanyaan yang dia referensikan):
// <summary>
// Get the name of a static or instance property from a property access lambda.
// </summary>
// <typeparam name="T">Type of the property</typeparam>
// <param name="propertyLambda">lambda expression of the form: '() => Class.Property' or '() => object.Property'</param>
// <returns>The name of the property</returns>
public string GetPropertyName<T>(Expression<Func<T>> propertyLambda)
{
var me = propertyLambda.Body as MemberExpression;
if (me == null)
{
throw new ArgumentException("You must pass a lambda of the form: '() => Class.Property' or '() => object.Property'");
}
return me.Member.Name;
}
Pemakaian:
// Static Property
string name = GetPropertyName(() => SomeClass.SomeProperty);
// Instance Property
string name = GetPropertyName(() => someObject.SomeProperty);
Sekarang dengan kemampuan keren ini, saatnya menyederhanakan metode ExposeProperty. Memoles gagang pintu adalah pekerjaan berbahaya ...
Terimakasih semuanya.
sumber
Jawaban:
Menggunakan GetMemberInfo dari sini: Mengambil nama Properti dari ekspresi lambda Anda dapat melakukan sesuatu seperti ini:
RemoteMgr.ExposeProperty(() => SomeClass.SomeProperty)
sumber
GetMemberInfo
? Saya tidak dapat menemukan apa pun dengan paket 'utilitas umum' untuk Perpustakaan Microsoft Enterprise, yang sepertinya ditunjukkan oleh MSDN berisi metode itu. Ada paket "tidak resmi" tetapi tidak resmi tidak menginspirasi. Jawaban JimC , yang didasarkan pada yang satu ini, jauh lebih ringkas dan tidak bergantung pada perpustakaan yang tampaknya tidak tersedia.Dengan C # 6.0, ini bukan masalah seperti yang dapat Anda lakukan:
Ungkapan ini diselesaikan pada saat kompilasi ke
"SomeProperty"
.Dokumentasi MSDN dari nama .
sumber
const string
! Luar biasaRaiseProperty
di WPF! Gunakan RaisePropertyChanged (nameof (property)) alih-alih RaisePropertyChanged ("property")Ada peretasan terkenal untuk mengekstraknya dari ekspresi lambda (ini dari kelas PropertyObserver, oleh Josh Smith, di yayasan MVVM-nya):
Maaf, ini tidak ada konteks. Ini adalah bagian dari kelas yang lebih besar di mana
TPropertySource
kelas yang berisi properti. Anda bisa membuat fungsi generik di TPropertySource untuk mengekstraknya dari kelas. Saya sarankan untuk melihat kode lengkap dari Yayasan MVVM .sumber
public static string GetPropertyName<TPropertySource>(Expression<Func<TPropertySource, object>> expression)
lalu memanggil seperti:var name = GetPropertyName<TestClass>(x => x.Foo);
Oke, inilah yang akhirnya saya buat (berdasarkan jawaban yang saya pilih dan pertanyaan yang dia referensikan):
Pemakaian:
sumber
Kelas PropertyInfo akan membantu Anda mencapai ini, jika saya mengerti dengan benar.
Metode Type.GetProperties ()
Apakah ini yang Anda butuhkan?
sumber
Anda dapat menggunakan Refleksi untuk mendapatkan nama properti yang sebenarnya.
http://www.csharp-examples.net/reflection-property-names/
Jika Anda membutuhkan cara untuk menetapkan "Nama String" ke properti, mengapa Anda tidak menulis atribut yang dapat Anda pantulkan untuk mendapatkan nama string?
sumber
Saya memodifikasi solusi Anda untuk menghubungkan beberapa properti:
Pemakaian:
sumber
Berdasarkan jawaban yang sudah ada dalam pertanyaan dan pada artikel ini: https://handcraftsman.wordpress.com/2008/11/11/how-to-get-c-property-names-without-magic-strings/ I Saya mempresentasikan solusi saya untuk masalah ini:
Dan Tes yang juga menunjukkan penggunaan untuk properti contoh dan statis:
sumber
Pertanyaan lama, tetapi jawaban lain untuk pertanyaan ini adalah membuat fungsi statis di kelas pembantu yang menggunakan CallerMemberNameAttribute.
Dan kemudian gunakan seperti:
sumber
Anda dapat menggunakan kelas StackTrace untuk mendapatkan nama fungsi saat ini, (atau jika Anda meletakkan kode dalam suatu fungsi, maka turunkan level dan dapatkan fungsi panggilan).
Lihat http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace(VS.71).aspx
sumber
Saya telah menggunakan jawaban ini untuk efek yang sangat baik: Dapatkan properti, sebagai string, dari Ekspresi <Func <TModel, TProperty >>
Saya sadar saya sudah menjawab pertanyaan ini beberapa waktu lalu. Satu-satunya keuntungan jawaban saya yang lain adalah bahwa ia berfungsi untuk properti statis. Saya menemukan sintaks dalam jawaban ini jauh lebih berguna karena Anda tidak harus membuat variabel dari jenis yang ingin Anda refleksikan.
sumber
Saya mengalami beberapa kesulitan menggunakan solusi yang sudah disarankan untuk kasus penggunaan khusus saya, tetapi akhirnya menemukan jawabannya. Saya tidak berpikir kasus spesifik saya layak untuk pertanyaan baru, jadi saya memposting solusi saya di sini untuk referensi. (Ini sangat erat kaitannya dengan pertanyaan dan memberikan solusi bagi orang lain dengan kasus serupa dengan saya).
Kode saya berakhir dengan tampilan seperti ini:
Bagian penting bagi saya adalah bahwa di
CompanyControl
kelas kompiler hanya akan memungkinkan saya untuk memilih properti booleanICompanyViewModel
yang membuatnya lebih mudah bagi pengembang lain untuk memperbaikinya.Perbedaan utama antara solusi saya dan jawaban yang diterima adalah bahwa kelas saya generik dan saya hanya ingin mencocokkan properti dari tipe generik yang boolean.
sumber
Begitulah cara saya mengimplementasikannya, alasan di baliknya adalah jika kelas yang Anda inginkan untuk mendapatkan nama dari anggotanya tidak statis maka Anda perlu membuat instanse untuk itu dan kemudian mendapatkan nama anggota. jadi generik di sini datang untuk membantu
penggunaannya seperti ini
sumber