2016-09-07 5 views
-2

値が変更された場合にイベントを発生させ、1つの値を格納するPropertyというクラスがあります。 Observableという別のクラスがあり、プロパティの辞書を入れたいと思っています。私は以下の例を持っています。どのように私はオブジェクトを変更することができます辞書に格納されているプロパティの種類を取得することができますか?型引数を持つクラスへのC#キャストオブジェクト

プロパティクラス:

public class Property<T> 
{ 
    public T Value { get; set; } 
} 

観察可能なクラス:

public class Observable 
{ 
    public readonly Dictionary<string, object> 
       Properties = new Dictionary<string, object>(); 

    public Property<T> Get<T>(string name) 
    { 
     object obj; 
     Properties.TryGetValue(name, out obj); 
     return (Property<T>) obj; 
    } 
} 

EDIT は、これは私が取得していますエラーです - 未処理の例外:System.InvalidCastExceptionの:のオブジェクトをキャストすることができませんが'System.String'を入力して 'ConsoleApplication.Property`1 [System.String]'と入力します。

また、Get関数を取り除き、より良い型を知る必要のないものに置き換えることができた場合は、

更新:名前で型をハッシュして型を取得する方法はありますか? (更新ポスト用)

+0

http://stackoverflow.com/questions/2399710/how-to-get-type-of-tkey-and-tvalue-given-a-dictionarytkey-tvalue-type –

+0

Get (...) 'が成功するでしょうか?あなたが提供したコードの何が間違っていますか? –

+0

それは私が求めているものではありません。私は辞書の値の型を取得したくない、私はプロパティ内の値の型を取得したい。 –

答えて

2

EDIT:

は、タイプと名前をハッシュすることによってタイプを取得する方法はありますか?

このようなものをお探しですか? dotnetfiddle link

public interface IProperty 
{ 
    object Value { get; } 
    Type TypeOfValue { get; } 
} 

public class Property : IProperty 
{ 
    public object Value { get; set; } 
    public Type TypeOfValue { get; set; } 
    public override string ToString() { return TypeOfValue.FullName + ": " + Value; } 
} 

public class Observable 
{ 
    public readonly Dictionary<string, Property> 
     Properties = new Dictionary<string, Property>(); 

    // use interface so consumer of your property can't mess with the 
    // type or value stored in your dictionary within Observable 
    public IProperty Get(string name) 
    { 
     Property obj; 
     if (Properties.TryGetValue(name, out obj)){ 
      return obj; 
     } 

     // throw something which makes more sense to you 
     throw new ArgumentException(name + " does not exist in the dictionary"); 
    } 

    // sample of how you'd store these properties 
    public void Set(string name, object val) 
    { 
     if (Properties.ContainsKey(name)){ 
      Properties[name].Value = val; 
      Properties[name].TypeOfValue = val.GetType(); 
     } else { 
      Properties[name] = new Property { 
       Value = val, 
       TypeOfValue = val.GetType() 
      }; 
     } 
    } 
} 

ORIGINAL ANSWER:

それはあなたが誤って代わりにProperty<string>Observableの内側にあなたの辞書にstringを挿入している、との問題はあなたが「コードにないので、場合ている可能性があります代わりにProperty<string>の代わりにstringを挿入する場合はどこにでも投稿してください。

無効なキャスト例外が気に入らない場合は、2つの方法があります。

解決策1:関数がスローするエラーをカスタマイズします。

Get<T>(...)の署名を保持したい場合は、エラー処理をお勧めします。表示されるエラーは、辞書のプロパティがタイプstringで、タイプがProperty<string>ではないためです。次のコードは、より多くのエラー処理のために作業するものを提供します。

public class Observable 
{ 
    public readonly Dictionary<string, object> 
     Properties = new Dictionary<string, object>(); 

    public Property<T> Get<T>(string name) 
    { 
     object obj; 
     if (Properties.TryGetValue(name, out obj)){ 
      try { 
       return (Property<T>) obj; 
      } catch(InvalidCastException){ 
       // throw something which makes more sense to you 
       throw new ArgumentException("Could not cast the given object to the desired type"); 
      } 
     } 

     // throw something which makes more sense to you 
     throw new ArgumentException(name + " does not exist in the dictionary"); 
    } 
} 

解決方法2:一般object

public class Observable 
{ 
    public readonly Dictionary<string, object> 
     Properties = new Dictionary<string, object>(); 

    public object Get(string name) 
    { 
     object obj; 
     if (Properties.TryGetValue(name, out obj)){ 
      return obj; 
     } 

     // or do whatever you want when the given key doesn't exist. 
     return null; 
    } 
} 
0

インデクサは、追加の構成要素を使用せずに、あなたの問題を解決することがあり返します。 あなたがいるかどうか見てください私はあなたを明確にしても分かりませんが、私は助けようとします) 私にとって、質問は次のように言い換えられます。 アップキャストタイプの最も特定のタイプを判別することは可能ですか?ここで

は、最初にメモリに割り当てられたどのような種類見ることができるようにWriteLineメソッド操作の出力は「PROJECT_NAME」.Managerであなたに

public class Employee 
{ 
    public int salary { get; set; } 

} 

public class Manager : Employee 
{ 

} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Manager man = new Manager(); 
     System.Object emp = (object) man; 
     Console.WriteLine(emp.GetType()); 
    } 
} 

を助けるかもしれないコードです。それらに精通していない。

関連する問題