2016-09-23 7 views
2

ジェネリックに問題があります。私はジェネリッククラスを書いています。私はこのクラスから他のクラスを派生させます。非ジェネリッククラスのジェネリックを使用

最後に、この派生クラスを別のクラスで使用したいと思いますが、解決方法を見つけられませんでした。これまでのところ良い

// Generic base class 
public class Information<T> 
{ 
    public T StatusCode; 
    public bool Changed; 
} 

public class Status1 : Information<Status1.Codes> 
{ 
    public enum Codes { None = 0, } 
    public string AdditionalStatusInformation; 

    public Status1() 
    { 
     StatusCode = Codes.None; 
    } 
} 

public class Status2 : Information<Status2.Codes> 
{ 
    public enum Codes { OK = 0, } 

    public Status2() 
    { 
     StatusCode = Codes.OK; 
    } 
} 

すべて:

は、ここに私の簡単な例です。私はJsonを使用してこの情報を送信しています。このアプローチは受信機と送信機の両方で機能します。 Status1クラスとStatus2クラスでうまく動作します。

最後に、私はStatus1クラスまたはStatus2クラスを使用したい汎用のErrorReporterクラスを持っています。これは不可能だと思われる。

public class ErrorReporter<T> where T : Information<T> 
{ 
    public readonly T Info = Activator.CreateInstance<T>(); 

    public void Update() 
    { 
     if (Info.Changed) 
     { 
      Console.WriteLine(Info.StatusCode.ToString()); 
      Console.WriteLine(JsonConvert.SerializeObject(Info)); 
     } 
    } 
} 

このクラスを正しくインスタンス化する方法はありません。

私は、これらの

new ErrorReporter<Status1>() 
new ErrorReporter<Status1.Codes>() 
new ErrorReporter<Information<Status1.Codes>() 

を試してみました私は

The type 'TestApp.Program.Status1' cannot be used as type parameter 'T' in 
the generic type or method 'TestApp.Program.ErrorReporter<T>'. 
There is no implicit reference conversion from 'TestApp.Program.Status1' to 
'TestApp.Program.Information<TestApp.Program.Status1>'. 

または同様のエラーメッセージを取得しています。

おそらく、ErrorReporterクラスをInformationクラスに移動する必要があります。

しかし、私のErrorReporterクラスから新しいオブジェクトをインスタンス化する正しい方法は何ですか?それも可能ですか?

答えて

0

Information<T>から派生するTが必要です。これは欲しいものではありません。

public class ErrorReporter<T, S> where T : Information<S>, new() 
{ 
    public readonly T Info = new T(); 
} 
0

問題:あなたは、反射呼び出しを削除することができ、少し余分で

public class ErrorReporter<T, S> where T : Information<S> 
{ } 

は、私はあなたがジェネリックの型引数を指定する必要がありますどこで、これを必要と推測します

  • 2つの目的のためにTを使用しようとしていることです。

    public class ErrorReporter<TSource, TCode> where TSource : Information<TCode> 
    { 
        public readonly TSource Info = Activator.CreateInstance<TSource>(); 
    
        public void Update() 
        { 
         if (Info.Changed) 
         { 
          Console.WriteLine(Info.StatusCode.ToString()); 
          Console.WriteLine(JsonConvert.SerializeObject(Info)); 
         } 
        } 
    } 
    
    :あなたはそれにStatusCode)ステータスコードの
  • タイプを呼んでいる(それは今、あなたはだけではなく、2種類のパラメータで、一般的なErrorReporterを作ることができる

Information<T>ための型引数)です

次にあなたが使用できます。

new ErrorReporter<Status1, Status1.Codes>() 

それともでしメートル単にコードタイプで、それは一般的なAKEが、反射して、ソースを構築避ける:

public class ErrorReporter<T> 
{ 
    // You could expose this as a property if you want. I would 
    // advise against exposing it as a field 
    private readonly Information<T> source; 

    public ErrorReporter(Information<T> source) 
    { 
     this.source = source; 
    } 

    public void Update() 
    { 
     if (Info.Changed) 
     { 
      Console.WriteLine(source.StatusCode.ToString()); 
      Console.WriteLine(JsonConvert.SerializeObject(source)); 
     } 
    } 
} 

としてそれを構築:あなたの両方に

var reporter = new ErrorReporter<Status1.Codes>(new Status1()); 
+0

感謝。今私の間違いを見る... – itix

関連する問題