2008-11-14 15 views
13

Aşağıdaki sınıf verildiğinde:C# özellikleri için kullanılabilir bir temsilci var mı?

class TestClass { 
    public void SetValue(int value) { Value = value; } 
    public int Value { get; set; } 
} 

TestClass tc = new TestClass(); 
Action<int> setAction = tc.SetValue; 
setAction.Invoke(12); 

yapabilirim. Yöntem yerine mülk kullanarak aynı şeyi yapmak mümkün mü? Tercihen .net'e yerleşik bir şeyle.

cevap

21

Sen yansıma kullanarak temsilci oluşturabilirsiniz:

Action<int> valueSetter = (Action<int>)Delegate.CreateDelegate(typeof(Action<int>), tc, tc.GetType().GetProperty("Value").GetSetMethod()); 

veya özelliğini ayarlar anonim yönteme temsilci yaratma;

Action<int> valueSetter = v => tc.Value = v; 

Düzenleme: CreateDelegate() için yanlış bir şekilde kullanılan aşırı yükleme, hedef olarak alan ve nesneyi kullanmanız gerekir. Sabit.

+0

Bence bu, sahip olduğum ihtiyaçlar için işe yarayacak. Teşekkürler! –

+0

C# ilk dilimin olması gerektiği düşünülürse gerçekten bu şeyi anladım (yansıma kullanarak bir delege yaratıyor) - harika sesler – JohnIdol

+1

Ve .net 2.0 için bir eylem yapabilir valueSetter = temsilci (int değer) {tc .Value = değer; } –

3

Özellikleri ikisini varsa

System.Reflection.PropertyInfo

göster ... Gerçekten bu yüzden onları yürütmek sonra temsilci (set_PROPERTY ve get_PROPERTY) almak ve mümkün olmalıdır yansıma kullanarak, .NET yöntemleri etrafında sarmalayıcıların vardır - GetGetMethod ve GetSetMethod değerini almak/ayarlamak için kullanabileceğiniz yöntemler.

Yani yazabilirsiniz:

var propertyInfo = typeof (TestClass).GetProperty ("Value"); 

var setMethod = property.GetSetMethod(); // This will return a MethodInfo class. 
+2

C# belirtimi, herhangi bir özellik P için get_P ve set_P yöntemlerini saklasa da, bu yöntemleri özelliklerde kullanmak için uygulama gerektirmez. Bu uygulama detayı yapar. Belgelenmemiş uygulama ayrıntılarına güvenmeyin. –

+4

PropertyInfo sınıfını ve GetGet/SetMethod kullanarak artık bir uygulama sorunu değil. Bu noktada çerçevenin bir parçası. – Kieron

+0

Kieron: Yeterince adil. –

12

Bunu yapmanın üç yolu vardır; Birincisi GetGetMethod()/GetSetMethod() kullanmak ve Delegate.CreateDelegate ile bir temsilci oluşturmaktır. İkincisi bir lambda (yansıma için çok fazla kullanılmaz!) [Yani. X => x.Foo]. Üçüncüsü ise İfade (.NET 3.5). Belirli örneğine işaret temsilci isterseniz, lambda için kapanışları kullanabileceği

 TestClass foo = new TestClass(); 
     foo.Value = 1; 
     Console.WriteLine("Via property: " + foo.Value); 

     lambdaSet(foo, 2); 
     Console.WriteLine("Via lambda: " + lambdaGet(foo)); 

     reflSet(foo, 3); 
     Console.WriteLine("Via CreateDelegate: " + reflGet(foo)); 

Not:

lambda kullanımını göstermek için

class TestClass 
    { 
     public int Value { get; set; } 
    } 
    static void Main() 
    { 
     Func<TestClass, int> lambdaGet = x => x.Value; 
     Action<TestClass, int> lambdaSet = (x, val) => x.Value = val; 

     var prop = typeof(TestClass).GetProperty("Value"); 
     Func<TestClass, int> reflGet = (Func<TestClass, int>) Delegate.CreateDelegate(
      typeof(Func<TestClass, int>), prop.GetGetMethod()); 
     Action<TestClass, int> reflSet = (Action<TestClass, int>)Delegate.CreateDelegate(
      typeof(Action<TestClass, int>), prop.GetSetMethod()); 
    } 

en kolay ;-p olduğunu veya örnek oluşturan ve kabul eden CreateDelegate'in aşırı yüklenmesi.

+1

Örnekleri göndermek ister misiniz? –

+2

btw, Bir İfade örneğini yayınlamadım, çünkü ayrıntılı olma eğilimindedir. Ancak, bazı İfade mesajları benim blogumda: http://marcgravell.blogspot.com/search/label/expression –

+0

Bu kolay anlaşılması için çok kolay bir örnek! –

İlgili konular