2011-10-25 4 views
3

、C#オブジェクトインスタンスのカスタムプロパティの* value *を取得しますか? .NET 4を使用して

はのは、私がCustomTypeDescriptorを拡張するクラスInfoがあるとしましょう。クラスInfoのインスタンスは、実行時にロード<string, object>ペアの辞書を持っています。

Infoの各インスタンスは異なる特性を有するように)私は、プロパティとして辞書キーを公開できるようにしたいです。プロパティの値は、辞書内の対応する値にする必要があります。私は、露光特性のために暇

public override PropertyDescriptorCollection GetProperties() 
    { 

     var orig = base.GetProperties(); 
     var newProps = dictionary.Select(kvp => 
         TypeDescriptor.CreateProperty(
          this.GetType(), 
          kvp.key, 
          typeof(string))); 
     return new PropertyDescriptorCollection(
        orig.Cast<PropertyDescriptor>() 
        .Concat(newProps) 
        .ToArray()); 
    } 

問題があるが、どのように私はそれらの値を得るのですか?

var info = new Info(new Dictionary<string, object>{{"some_property", 5}}; 
var prop = TypeDescriptor.GetProperties(i_info)["some_property"]; 
var val = prop.GetValue(i_info); //should return 5 

私はprop.GetValue()が呼び出されたときに制御を取得するために見つけた唯一の方法は、GetPropertyOwner(PropertyDescriptor pd)を上書きすることでしたが、私はそれを理解する方法は、それは私がコンパイルされている別のタイプ一致実数(のインスタンスを返すことを期待します)プロパティです。

私は自分自身(この例では、そのキーが一致プロパティ名を辞書に値を返す)プロパティの実際の実装を書くことができるようにしたいと思います。

これは可能ですか?

答えて

3

PropertyDescriptorクラスを独自に実装して、GetValueメソッドをオーバーライドする必要があります。だからではなく、TypeDescriptor.CreatePropertyの新しいMyCoolPropertyDescriptor(dictionary, kvp.Key)などを使用します。ここで

は、それを実現できるかのサンプルです:

 

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 

namespace ConsoleApplication1 
{ 
    internal sealed class MyCoolPropertyDescriptor : PropertyDescriptor 
    { 
     private Func<object, object> propertyGetter; 
     private Action<object, object> propertySetter; 

     public MyCoolPropertyDescriptor(
      string name, 
      Func<object, object> propertyGetter, 
      Action<object, object> propertySetter) 
      : base(name, new Attribute[] {}) 
     { 
      this.propertyGetter = propertyGetter; 
      this.propertySetter = propertySetter; 
     } 

     public override bool CanResetValue(object component) 
     { 
      return true; 
     } 

     public override System.Type ComponentType 
     { 
      get { return typeof(object); } 
     } 

     public override object GetValue(object component) 
     { 
      return this.propertyGetter(component); 
     } 

     public override bool IsReadOnly 
     { 
      get { return false; } 
     } 

     public override System.Type PropertyType 
     { 
      get { return typeof(object); } 
     } 

     public override void ResetValue(object component) 
     { 
      this.propertySetter(component, null); 
     } 

     public override void SetValue(object component, object value) 
     { 
      this.propertySetter(component, value); 
     } 

     public override bool ShouldSerializeValue(object component) 
     { 
      return false; 
     } 
    } 

    public sealed class Info : CustomTypeDescriptor 
    { 
     IDictionary<string, object> properties; 

     public Info(IDictionary<string, object> properties) 
     { 
      this.properties = properties; 
     } 

     public override PropertyDescriptorCollection GetProperties() 
     { 
      var orig = base.GetProperties(); 
      var newProps = this.properties 
       .Select(kvp => new MyCoolPropertyDescriptor(
        kvp.Key, 
        o => ((Info)o).properties[kvp.Key], 
        (o, v) => ((Info)o).properties[kvp.Key] = v)); 

      return new PropertyDescriptorCollection(orig 
       .Cast<PropertyDescriptor>() 
       .Concat(newProps) 
       .ToArray()); 
     } 
    } 

    internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      var info = new Info(new Dictionary<string, object>{{"some_property", 5}}); 
      var prop = TypeDescriptor.GetProperties(info)["some_property"]; 
      var val = prop.GetValue(info); //should return 5 
      Console.WriteLine(val); 
     } 
    } 
} 
 
2

CustomTypeDescriptorの私の理解では、それはグリッド、たとえば、に余分なプロパティを公開するためにデータバインディングを可能にするということである、実際には存在しないことクラス。実際のクラスがプロパティを公開するように、CLRを拡張するものではありません。

実際のCLRプロパティが必要な場合は、後で考えている機能の種類を取得するには、DynamicObjectまたはExpandoObjectを参照する必要があります。

+0

ダイナミックプロパティにCustomTypeDescriptorを使用することは可能ですが(ストレッチしているかもしれませんが)しかし、「動的な」提案に対して+1。私はすでにそれを使用する方法を学ぶ必要があります:) –

関連する問題