An abstract class and interface with the same common method

I am writing two APIs that I will use with many of my projects. In some projects, I use one of the APIs and the other, but most of my projects will use both. I try to design them as if they are completely separate, but I am fighting for one thing.

namespace FirstApi {
    public abstract class MyBaseClass {
        //constructor, some methods and properties

        public IEnumerable<T> Search<T>() where T : MyBaseClass, new() {
            //search logic here. must use generics as I create new instances of T here
        }
    }
}


namespace SecondApi {
    public interface IMyInterface {
        //some property and method signatures

        IEnumerable<T> Search<T>() where T : IMyInterface, new();
    }
}

namespace MyProject {
    public class MyDerivedClass : MyBaseClass, IMyInterface {

    }
}

Both APIs require this search method. The second API has some functions in other classes that call IMyInterface.Search<T>(), and I would like those classes that inherit MyBaseClassto use the function Search<T>defined in MyBaseClass.

:. "T" "MyBaseClass.Search()" "T" "IMyInterface.Search()", .

. T , . , # 2.0 (# return ), !

, , ?

:

, , API.

public abstract class ApiAdapter<TAdapter> : MyBaseClass, IMyInterface where TAdapter: MyBaseClass, IJsonObject, new()
{
    IEnumerable<T> IJsonObject.Search<T>()
    {
        foreach (TAdapter row in base.Search<TAdapter>())
            yield return (T)(IMyInterface)row;
    }
}

.

public class Client : ApiAdapter<Client> {
    //everything else can go here
}
+3
5

, , , , .

@IndigoDelta, , . , ; , , :

. , T , .

; , , , , IMyInterface.Search, - , . , API , , :

namespace MyProject
{
  using FirstApi;
  using SecondApi;

  public class SecondAPIAdapter<T2> : MyBaseClass, IMyInterface
    where T2 : SecondAPIAdapter<T2>, new()
  {
    #region IMyInterface Members
    IEnumerable<T> IMyInterface.Search<T>()
    {
      return Search<T2>().Cast<T>();
    }
    #endregion
  }

  //now you simply derive from the APIAdapter class - passing
  //in your derived type as the generic parameter.
  public class MyDerivedClass : SecondAPIAdapter<MyDerivedClass>
  { }
} 
+2

, .

    public class MyDerivedClass : BasicTestApp.FirstApi.MyBaseClass, BasicTestApp.SecondApi.IMyInterface
    {
        IEnumerable<T> SecondApi.IMyInterface.Search<T>()
        {
            // do implementation
        }
    }

, , MyBaseClass Search, , , IMyInterface, Search<T>. , T , . where T : BasicTestApp.FirstApi.MyBaseClass, IMyInterface, new(); , , API

. , .

        IEnumerable<T> SecondApi.IMyInterface.Search<T>()
        {
            var results = base.Search<MyDerivedClass>();

            return results.Cast<T>();
        }
+4

, IMyInterface.Search - .

+1

.

public class MyDerivedClass : MyBaseClass, IMyInterface
{
    // The base class implementation of Search inherited

    IEnumerable<T> IMyInterface.Search<T>()
    {
        // The interface implementation
        throw new NotImplementedException();

        // this would not work because base does not implement IMyInterface 
        return base.Search<T>();
    }     
}

, . , , ( .NET 4.0), , , .

+1

, , , :

public interface IMyInterface<in T>
{
    //some property and method signatures

    IEnumerable<U> Search<U>() where U : T, new();
}

T, , T:

public abstract class MyBaseClass : IMyInterface<MyBaseClass>
{
    public virtual IEnumerable<T> Search<T>() where T : MyBaseClass, new()
    {

    }
}

, :

public class MyDerivedClass : MyBaseClass
{

}

:

var derived = new MyDerivedClass();
IMyInterface<MyDerivedClass> iface = impl;

var results = iface.Search<MyDerivedClass>();
0

All Articles