简体   繁体   English

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

[英]Implement non-generic interface using generic class

I have custom control and I have interface this control exposes to it's users. 我有自定义控件,我有接口这个控件暴露给它的用户。

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

Need to implement it like so: 需要像这样实现它:

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

So, how do I tell that this generic method is really implementation of interface? 那么,我怎么告诉这个泛型方法真的是接口的实现呢?

Right click on ILookupDataProvider. 右键单击ILookupDataProvider。 Select Implement Interface . 选择Implement Interface Fill out the method provided without changing the signature. 在不更改签名的情况下填写提供的方法。


Edit: I thought someone would come on here and show you how to forward the call. 编辑:我想有人会来这里告诉你如何转发电话。 Oh well. 那好吧。

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

if you want the forwarding method to only be accessible through the interface, use this method signature: 如果您希望转发方法只能通过接口访问,请使用此方法签名:

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

The type parameter doesn't have any bearing one way or another on the derived class being an implementation of the interface. 类型参数在作为接口实现的派生类上没有任何方式。

for instance: 例如:

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 and B are implementations of I. Bot A和B是I的实现。

If you right-click on the interface and choose implement interface, it will do it for you, but the way you have the interface designed, it wont match the interface's definition. 如果右键单击界面并选择实现界面,它将为您完成,但是您设计界面的方式与界面的定义不匹配。

To make them match, you can do the following (now the implementation will match the signature of the interface): 要使它们匹配,您可以执行以下操作(现在实现将匹配接口的签名):

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

    public class LookupDataProvider<T> : ILookupDataProvider<T>

If you can change the class to be a generic method you could do this: 如果您可以将类更改为通用方法,则可以执行以下操作:

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

}

Edit In regards to Kirk's comment you need to move the type parameter on the method. 编辑关于Kirk的注释,您需要在方法上移动类型参数。 While you could leave it on the class as well that can lead to interesting things. 虽然你可以把它留在课堂上,这可能会导致有趣的事情。 Run this code for example: 运行此代码例如:

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

}

This actually is a warning (and I'm surprised it's not considered an exception) 这实际上是一个警告(我很惊讶它不被视为例外)

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

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