2011-11-07 6 views
1

私はカスタムコントロールを持っており、このコントロールはユーザーに公開するインターフェイスを持っています。ジェネリッククラスを使用した非ジェネリックインターフェイスの実装

public interface ILookupDataProvider 
    { 
     void GetDataAsync(string parameters, Action<IEnumerable<object>> onSuccess, Action<Exception> onError); 
    } 

ので、同じようにそれを実装する必要があります。だから、

public class LookupDataProvider<T> : ILookupDataProvider 
    { 

     public void GetDataAsync(string parameters, Action<IEnumerable<T>> onSuccess, Action<Exception> onError) 
     { 
      var query = new EntityQuery<T>(); 
      this.entityManager.ExecuteQueryAsync(
       query, 
       op => 
        { 
         if (op.CompletedSuccessfully) 
         { 
          onSuccess(op.Results); 
         } 
         else if (op.HasError) 
         { 
          onError(op.Error); 
         } 
        }); 
     } 
    } 

、どのように私は、この一般的な方法は、実際のインターフェースの実装であることを教えていますか?

答えて

1

では、次の(現在の実装は、インタフェースの署名と一致します)を行うことができ、それらを一致させるには:カークさんのコメントに関しては

public class LookupDataProvider : ILookupDataProvider 
{ 

    public void GetDataAsync<T>(string parameters, Action<IEnumerable<T>> onSuccess, Action<Exception> onError) 
    { 

    } 

    void ILookupDataProvider.GetDataAsync(string parameters, Action<IEnumerable<object>> onSuccess, Action<Exception> onError)   
    { 
     this.GetDataAsync<Object>(parameters, onSuccess, onError); 
    } 

} 

編集 あなたはメソッドに型パラメータを移動する必要があります。あなたはクラスにそれを残すこともできますが、興味深いものにつながる可能性があります。たとえば、このコードを実行します。

class Program 
{ 
    static void Main(string[] args) 
    { 
     var b = new Foo<Guid>(); 
     b.Bar(); 

     Console.ReadLine(); 
    } 
} 



public class Foo<T> 
{ 

    public void Bar<T>() 
    { 
     Console.WriteLine("Bar<T>() : " +typeof(T).Name); 
    } 

    public void Bar()   
    { 

     Console.WriteLine("Bar() : " + typeof(T).Name); 
     this.Bar<string>(); 
    } 

} 

これは実際には警告です(と私はそれは例外と考えられていない驚いている)

+0

私はこれが正しい解決策だと思います - なぜ、クラスがもはやジェネリックパラメータを取らないように変更するのですか? –

+0

@KirkWollは私の編集 – JoshBerke

+0

を見ていますが、元の答えのように明示的なインターフェイス実装を使用していますが、クラスの型パラメータを残すことができます。私はそれが本質的ではないと言っているわけではありませんが、OPの元のコードをそれ以下に変更することが必要です。 –

1

ILookupDataProviderを右クリックします。 Implement Interfaceを選択します。署名を変更せずに、提供されたメソッドを記入してください。


編集:私は誰かがここに来て、通話を転送する方法を示したと思った。しかたがない。

public void ILookupDataProvider.GetDataAsync(
    string parameters, 
    Action<IEnumerable<object>> onSuccess, 
    Action<Exception> onError) 
1

型パラメータが派生クラス上の任意のベアリング一つの方法または別のを持っていない:あなたは、転送方法が唯一のインターフェースを介してアクセスできるようにしたい場合は

public class LookupDataProvider<T> : ILookupDataProvider 
{ 
    public void GetDataAsync(
    string parameters, 
    Action<IEnumerable<object>> onSuccess, 
    Action<Exception> onError) 
    { 
    Action<IEnumerable<T>> onSuccessGeneric = x => onSuccess(x.OfType<object>()); 
    this.GetDataAsync(parameters, onSuccess, onError); 
    } 

    public void GetDataAsync(
    string parameters, 
    Action<IEnumerable<T>> onSuccess, 
    Action<Exception> onError) 
    { 
    // as you had it before. 
    } 
} 

、このメソッドのシグネチャを使用しますインタフェースの実装です。例えば

interface I 
{ 
    int X { get; } 
} 

class A : I 
{ 
    int X { get; set; } 
} 

class B<T> : I 
{ 
    void F(T t) {} 
    int X { get; set; } 
} 

ボットAとBは、インターフェイスを実装するインターフェイスを右クリックして選択した場合、それはあなたのためにそれを行うだろう、I.

+0

私はOPが作っているポイントは、署名が互換性がないためということだと思いますジェネリック版はインターフェイスを満たしていません。 –

1

の実装ですが、方法はインターフェイスが設計されていれば、インターフェイスの定義に一致しません。あなたはこれを行うことが一般的な方法であることがクラスを変更することができる場合

public interface ILookupDataProvider<T> 
    { 
     void GetDataAsync(string parameters, Action<IEnumerable<T>> onSuccess, Action<Exception> onError); 
    } 

    public class LookupDataProvider<T> : ILookupDataProvider<T> 
+0

+1これも理想的な解決策ですが、インターフェースを一般的に変更することができれば、IMHO – JoshBerke

+0

@Josh、私はAPIをアクセスする*非汎用*手段を提供することになります。 (例: 'IEnumerable'と' IEnumerable ') –

関連する問題