page 1 of 1
Comments: 10 | Views: 909

Let's suppose that I design an interface:

public interface IDoThis {
    void DoThis();
}
public class DoThis : IDoThis {
    void IDoThis.DoThis() {
        throw new NotImplementedException();
    }
}

I want to be able to expose a static factory method for all classes that implement this interface.

public interface IDoThis2 : IDoThis {
    static IDoThis CreateInstance(); // not allowed
}
public class DoThis2 : IDoThis2 {
    void IDoThis.DoThis() {
        throw new NotImplementedException();
    }
    static IDoThis CreateInstance() {
        return new DoThis2();
    }
}

How would you work around this apparent C# limitation? Or is this a wrong way to think about this, and, if so, how would you approach the problem?

how about using an abstract class? why is that method called CreateInstance, are all those classes supossed to be singletons?
Yeah - I've run up against that too. The only real work-arounds I see within an interface-based context are
  • create a static factory class+method that returns IDoThis objects (eg. based on an enumeration), or similarly

  • create a static generic factory class:
    public static T CreateInstance<T>(Enum DoThisType) where T: IDoThis{...}
Can't enforce private constructors though (if you're interested in a singleton).
Is this thread a joke? sorry if its not..
JChung2006 wrote:
How would you work around this apparent C# limitation? Or is this a wrong way to think about this, and, if so, how would you approach the problem?


It's not a limitation, it's how OOP works.

I recommend you read the GoF book "Design Patterns", it'll help demysterify a number of conventions and why-things-are-the-way-they-are thingies that often confuse beginners.

Anyway, the "workaround" is to use the Factory pattern.
JChung2006 wrote:

dcuccia wrote:Yeah - I've run up against that too. The only real work-arounds I see within an interface-based context are
  • create a static factory class+method that returns IDoThis objects (eg. based on an enumeration), or similarly
  • create a static generic factory class:
    public static T CreateInstance<T>(Enum DoThisType) where T: IDoThis{...}
Can't enforce private constructors though (if you're interested in a singleton).

I like the second idea! In fact, you can dispose with the enum.

public static class DoThisFactory {
    public static T CreateInstance<T>() where T : IDoThis, new() {
        return new T();
    }
}

Or

public static class Factory<S> {
    public static T CreateInstance<T>() where T : S, new() {
        return new T();
    }
}

Thank you! Smiley



But in order to use the factory CreateInstance method you need to qualify it with the closed form expression which is the type parameter for T, but if you know what type T should be, then why not just create a new instance of it directly there?

Interfaces work because I can pass around something knowing only that it fulfills a contract (e.g. IEnumerable), and can thus call the GetEnumerator() function on it regardless of the object's actual type because the compiler knows it has that function, because the object extends IEnumerator.

When it comes to static calls you no longer have the object being passed around. Your only mechanism of "getting" to the method you want to call is by knowing the type itself, but then having an interface is useless to you, because you can just call the type's method statically directly instead of using the interface. That's why interfaces don't have static methods.
page 1 of 1
Comments: 10 | Views: 909