使用泛型类实现非泛型接口

时间:2011-11-07 22:13:14

标签: c# silverlight asynchronous

我有自定义控件,我有接口这个控件暴露给它的用户。

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);
                        } 
                    });
        }
    }

那么,我怎么知道这个泛型方法实际上是接口的实现?

4 个答案:

答案 0 :(得分:1)

右键单击ILookupDataProvider。选择Implement Interface。在不更改签名的情况下填写提供的方法。


编辑:我想有人会来这里告诉你如何转发电话。哦,好吧。

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.
  } 
}

如果您希望只能通过接口访问转发方法,请使用此方法签名:

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

答案 1 :(得分:1)

类型参数在作为接口实现的派生类上没有任何方式承载。

例如:

interface I
{
  int X { get; }
}

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

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

Bot A和B是I的实现。

答案 2 :(得分:1)

如果右键单击界面并选择实现界面,它将为您完成,但是您设计界面的方式与界面的定义不匹配。

要使它们匹配,您可以执行以下操作(现在实现将匹配接口的签名):

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

    public class LookupDataProvider<T> : ILookupDataProvider<T>

答案 3 :(得分: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);
    }

}

修改 关于Kirk的注释,您需要在方法上移动类型参数。虽然你可以把它留在课堂上,这可能会导致有趣的事情。运行此代码,例如:

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>();
    }

}

这实际上是一个警告(我很惊讶它不被视为例外)