2017-07-08 8 views
-1

ようなタイプの変数を表現するのは、私は一般的な機能で働いているとしましょう:C#がタイプ

public interface IFoo 
{ 
    Type Type; 
    TValue Read<TValue>(); 
} 

public class Foo : IFoo {} 

var f = new Foo(); 

私が書きたいのですが:

var value = f.Read<f.Type>(); 

が、これはエラーを与える:

fは変数ですが、タイプのように使用されます

私は条件文を書くことができます:それは冗長だから

object value; 
if (f.Type == typeof(bool)) 
{ 
    value = f.Read<bool>(); 
} 
if (f.Type == typeof(byte)) 
{ 
    value = f.Read<byte>(); 
} 
... 

が、これは実際には動作しません、私は事前に可能なすべての種類が分からない場合は不完全なもの、および値は、オブジェクトの代わりのタイプであることがあります。

解決策はありますか?

+0

いいえ、あなたはこれを行うことはできません。「値」のタイプは何ですか?実行時の型情報を扱うときは、既知の型にキャストするまで動的に処理する必要があります。この場合、 'Object Read(Type t)'メソッドを追加して、このメソッドに委譲することで汎用バージョンを実装することができます。 – Lee

+0

インターフェイスを汎用化するとどうなりますか? – juharr

+0

厳密に言うと、shoulsを使用するプロパティを使用するため、エラーが発生します。var value = f.Read (); /私は全体的な意図をとにかく理解していません –

答えて

1

この問題はthrough reflectionまたはLINQ expressionsを解決する方法がありますが、問題の根本原因はIFooインターフェイスの貧弱な設計にあると思います。

あなたが必要とするすべては、読み取りからobject結果であり、これにインターフェイスを変更した場合:

public interface IFoo { 
    Type Type {get;} 
    object Read(); 
} 

これは、あなたがその私たちはobjectを取得するには、「元に戻す」にする必要があるジェネリック医薬品の使用を避けましょうだろう。

+0

' Object Read(); 'は' objectを出力したい場合に便利です。しかし、そうでなければ私は面倒な変換関数を書かなければならない – BaltoStar

2

タイプは、あなたがfooのインスタンスを作成します(そして、その後変更されません)時点で知られている場合は、汎用的なインタフェースは、最良の解決策のようになります。

public interface IFoo<T> 
{ 
    T Read(); 
} 

public class Foo<T> : IFoo<T> 
{ 
    public T Read() 
    { 
     Type type = typeof(T); 

     byte[] buffer = ...get byte array from wherever...; 
     object boxedResult; 

     using (MemoryStream ms = new MemoryStream(buffer)) 
     { 
      using (BinaryReader br = new BinaryReader(ms)) 
      { 
       if (type == typeof(int)) 
        boxedResult = br.ReadInt32(); 
       else if (type == typeof(long)) 
        boxedResult = br.ReadInt64(); 
       else if (type == typeof(bool)) 
        boxedResult = br.ReadBoolean(); 
       else if (type == typeof(byte)) 
        boxedResult = br.ReadByte(); 

       // ... 
       // other types you want to process 
       // ... 

       else boxedResult = null; 
      } 
     } 
     if (boxedResult != null) 
      return (T)boxedResult; 
     else 
      throw new Exception(string.Format("{0} not supported", type.Name)); 
    } 
} 

あなたはこのようなクラスを使用します:

var intFoo = new Foo<int>(); 
var boolFoo = new Foo<bool>(); 

int intVal = intFoo.Read(); 
bool boolVal = boolFoo.Read(); 
+0

彼にジェネリックFooの定義とFooインスタンスの作成 –

+0

@HelmutDタイプは 'Foo'のインスタンスごとに変更されず、' IFoo 'と' Fooは内部的に 'Foo'が' byte [] ' – BaltoStar

+0

"です。内部的にFooはbyte []です:つまり、あなたはバイトを読み込み、ジェネリック型に変換したいのですか?残念なことに、byte []はIConvertibleインターフェイスを実装していないので、明示的にバイトを汎用パラメータTが取ることができるすべての型に変換する必要があります。 –