繁体   English   中英

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

[英]Implement non-generic interface using generic class

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

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

那么,我怎么告诉这个泛型方法真的是接口的实现呢?

右键单击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)

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

例如:

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的实现。

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

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

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

    public class LookupDataProvider<T> : ILookupDataProvider<T>

如果您可以将类更改为通用方法,则可以执行以下操作:

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

}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM