简体   繁体   中英

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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