views:

244

answers:

3

The general rule is that I want to say, "T has a method with a String parameter which will return List." Put verbosely, we might call the interface ICanCreateListOfObjectsFromString. A possible application might be search.

It feels like it'd be nice to have a static method in my interface, but I know that's not allowed in C#. What is another approach to specify this kind of contract implementation on a class?

Edit: I would like to have the following code:

public interface ISearch
{
    static List<T> Search<T>(String s);
}

public class MyObject : ISearch {
    List<MyObject> Search(string s) {
        //...
    }
}

public List<T> DoFooSearch<T:ISearch> () {
        return T.Search("Foo");
}

public List<T> DoBarSearch<T:ISearch> () {
        return T.Search("Bar");
}

You can probably see why this code won't compile, but it expresses the spirit of what I'd like to achieve. I hope this clarifies my intention a bit.

A: 

Maybe the factory pattern is what you’re looking for.

Bombe
The idea is that I want to be able to browse these classes and say, "Oh, they implement ICanCreateListOfObjectsFromString." From what Bombe and Marc have said, it looks like I'd have to create factories for each of these types and say that the factory implements the interface.
Larsenal
Maybe that’s because what you want is pretty unclear. An interface _is_ a contract saying “this class has this and that method”. I think nobody is really sure why you keep on insisting on static methods for anything.
Bombe
It doesn't make sense to have a creation method be a member method. If it's not static then you have to sayMyClass mc = new MyClass();List<myClass> list = mc.GetAllMatching("Foo");I don't want to have to instantiate myClass just to call GetAllMatching.
Larsenal
A: 

The first options is to separate the two concerns:

  • one type to be the entity
  • one type to be the factory

Then you can create an interface for the factory, and use that (essentially like the previously static methods on the entity).

Another options is to talk in delegates - i.e. a Func<string,List<...>> (for some list type); then you can create a delegate trivially:

Func<string,List<...>> func = SomeType.SomeMethod; // static method

then you can pass func around, and (later) use it as:

List<...> data = func("abc");
Marc Gravell
With the delegates option, how would you setup the Interface?
Larsenal
The delegates version is *instead* of using an interface; delegates might be considered a single-method interface. I've added a usage example...
Marc Gravell
The delegate approach looks good, but is there any way to sort of "tag" the class as having an instance of that delegate method? If this sort of metadata was important, would I have to build something like a custom attribute?
Larsenal
+1  A: 

Sounds like you're trying to implement a Mixin... Something of that sort exists in C# 3.0, and they are named "Extension Methods".

What do allow you to do? Well, they allow you to create functions that work in types that you specify, and "add" methods to them. Since that type can be an interface, this lets you define concrete functions for an interface.

Admittedly, these functions aren't part of the interface code itself, but they also aren't part of any of the implementation of the interface. So it's a "glass half full" scenario.

(A brief search led me to Implementing Mixins with C# Extension Methods.)

Alternatively: if you don't require multiple inheritance for the classes that implement your interface, you can use abstract classes instead of interfaces, and implement concrete functions directly in them. But then again, that means you give up on inheriting from anything but that class (and implementing other interfaces.)

scraimer