1
public class Base<S>
{
    public static Derived<S, T> Create<T>()
    {
        return new Derived<S, T>(); //if not public, I wont get it here.
    }
}

public class Derived<S, T> : Base<S>
{
    public Derived() //the problem, dont want it public
    {

    }
}

This is the basic structure I have got.

Requirements:

1) I don't want an instance of Derived<,> to be constructed calling Derived<,> class at all, be it via constructor or a static method. I want it to be created only via Base<>. So this is out:

public class Derived<S, T> : Base<S>
{
    Derived()
    {

    }

    public static Derived<S, T> Create()
    {
        return new Derived<S, T>();
    }
}

2) Derived<,> class itself must be public (which means I can't private nest Derived<,> inside Base<>). Only then I can return Derived<,> from the static Create method in Base<>.

Is it possible?

nawfal
  • 70,104
  • 56
  • 326
  • 368
  • 1
    It feels like an inherently flawed design, since includes a circular dependency (A inherits from B, but B needs to know about A). Why can't the factory method go in the derived class? – T. Kiley Apr 18 '13 at 21:33
  • 1
    Can you give some context about *why* you have those requirements? Does the derived class itself need to be visible? – Jon Skeet Apr 18 '13 at 21:35
  • 1
    @T.Kiley I agree that this is non-standard, but isn't that essentially how `Encoding.UTF8`, etc. behave? (though probably not how they are implemented internally) – p.s.w.g Apr 18 '13 at 21:36
  • @JonSkeet yes, that's the second requirement. Except that the instantiation of derived class shouldn't be via it. – nawfal Apr 18 '13 at 21:37
  • @nawfal: Ah, I hadn't seen your second requirement. But can you not create a method declared to return a `Base`, which happens to actually create an instance of the derived type? Do callers really need the derived type? If they need some members of it, could that be described in an interface implemented by the derived type? – Jon Skeet Apr 18 '13 at 21:40
  • @p.s.w.g Interesting, though that does still return the base type (Encoding) not the derived type. Admittedly, this still has the circular dependency, but it is at least removed from the deceleration. – T. Kiley Apr 18 '13 at 21:42
  • @T.Kiley Yes that's true. You could go even one step further and perhaps make these interfaces, only using the static method as a factory stub. – p.s.w.g Apr 18 '13 at 21:47
  • @JonSkeet I get your point. But no derived type needs to returned. And the rationale behind is 1) being crazily purist, 2)more seriously, I hate the fuss involved in constructing/instantiating a generic classes with two type arguments - specifically this question: http://stackoverflow.com/questions/16082303/generic-base-class-wraps-nested-generic-class-to-reduce-type-argument-specificat Going by my current design I have more elegant call (also semantically correct ones wrt my application logic) I have foud a way for myself – nawfal Apr 18 '13 at 21:50
  • @JonSkeet a difference here from the link I provided is that here I want my derived class in this case to be public, whereas in examples in the link, the derived classes (implementations) should be private. Hence this question – nawfal Apr 18 '13 at 21:58
  • @T.Kiley you're right, my requirement *evokes* such a response. But in my case its a little different. A and B are so tightly coupled. They are classes like `Tuple<>`, `Tuple<,>`, `Tuple<,,>` where I need a static method on the base `Tuple<>` class for instantiation of all larger tuples. Its related to convenience of the caller. Forcing my clients to call something like `var f = new YodaYodaYoda(when all that can be easily inferred from constructor arguments)` is a bad idea when writing my API. – nawfal Apr 18 '13 at 22:05
  • @T.Kiley Was being a purist here so that I don't even let give my callers give that hassle. See my this question http://stackoverflow.com/questions/16082303/generic-base-class-wraps-nested-generic-class-to-reduce-type-argument-specificat to see what I specifically mean (how tightly coupled the classes are). *A static method on the base class to instantiate its children is not a sign of bad design, that would be instance method* – nawfal Apr 18 '13 at 22:08
  • I don't see anything "purist" about returning the derived class. I would create an appropriate public interface, make a private nested class which implements it, and declare the method to return the interface. – Jon Skeet Apr 18 '13 at 22:12
  • @JonSkeet I mean "my religious adherence to no constructor for derived class approach" was a little puritan, but your solution is better than mine indeed! Seems I cant think straightforward but only crooked :) (Could you) Make it an answer and there I go! ;) – nawfal Apr 18 '13 at 22:15
  • @JonSkeet well looking into my answer now, thats almost what I did, replace interface with abstract class :) – nawfal Apr 18 '13 at 22:16
  • @nawfal: Any reason you prefer an abstract class here? Unless you've *actually* got anything to put in there, I'd prefer an interface. – Jon Skeet Apr 18 '13 at 22:19
  • @JonSkeet you're 100% right! Especially when writing APIs, I should accept industry standards. I wrote an abstract class only because it came to my mind and not interface! :) That's why I was saying I did not think of the obvious choice in the first place. Thanks for the tip, I will surely use interface for my code. You may answer the same so that I can accept, otherwise I will accept mine which is not a bad answer to accept, too :P – nawfal Apr 18 '13 at 22:21
  • Done - although it's *slightly* different, as I'm reusing the `S` from `Base`, so that `Derived` itself only adds a single type parameter. – Jon Skeet Apr 18 '13 at 22:25

4 Answers4

3

You can make the derived class's constructor internal as in

public class Base<S>
{
    public static Derived<S, T> Create<T>()  // visible externally
    {
        return new Derived<S, T>(); 
    }
}

public class Derived<S, T> : Base<S>
{
    internal Derived() // not visible outside the current assembly
    {

    }
}
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
1

Reflection!

void Main()
{
    Derived dr = Base.GetDerived<Derived>();
}

public class Base
{
    public int ID { get; set; }
    public Base()
    {

    }

    public static T GetDerived<T>() where T : Base
    {
        T toReturn = (T)typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null).Invoke(null);
        return toReturn;
    }

}

public class Derived : Base
{
    private Derived()
    {

    }
}
iamkrillin
  • 6,798
  • 1
  • 24
  • 51
0

I achieved my requirement this way:

public abstract class Base<S>
{
    public static Derived<S, T> Create<T>() 
    {
        return new ReallyDerived<S, T>(); 
    }



    class ReallyDerived<T> : Derived<S, T>
    {
        public ReallyDerived()
        {

        }
    }
}

public abstract class Derived<S, T> : Base<S>
{

}

Now this works..

nawfal
  • 70,104
  • 56
  • 326
  • 368
0

I would declare a public interface, and make the implementation private within Base:

public class Base<S>
{
    public static IFoo<S, T> Create<T>()
    {
        return new Derived<T>(); //if not public, I wont get it here.
    }

    // Only generic in T, as we can use S from the containing class
    private class Derived<T> : Base<S>, IFoo<S, T>
    {
        public Derived()
        {
            ...
        }
    }
}

public interface IFoo<S, T>
{
    // Whatever members you want
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194