Gregzo
Gregzo

Reputation: 1194

Accessing a class nested in a generic class

Is this possible, or should I find another pattern and forget nesting?

Any help much appreciated!

Gregzo

public class OuterClass<T> where T : InnerClass, new()
{
    public T GetInnerInstance()
    {
        return new T();
    }

    public class InnerClass
    {
         public InnerClass
         {

         }
    }

}

public class Foo
{
    OuterClass<OuterClass.InnerClass> _instance; // nope
}

The goal is to let users extend InnerClass and use OuterClass as a factory.

Edit: for clarity, here's the full pattern, completed thanks to Greg's help:

public class OuterClass< ProductType, ReturnInterfaceType > where ProductType : InnerClass, ReturnInterfaceType, new()
                                                            where ReturnInterfaceType : MinInterface
{                   
    private string _privateName;

    public OuterClass( string name )
    {
        _privateName = name;
    }

    public ReturnInterfaceType GetProduct()
    {
        ProductType product = new ProductType();

        product.SetParent( this );

        return new ProductType();
    }

    public class InnerClass
    {
        protected OuterClass< ProductType, ReturnInterfaceType > _parent;

        public InnerClass(){} //empty ctor for generic new()

        public void SetParent( OuterClass< ProductType, ReturnInterfaceType > parent )
        {
            _parent = parent;
        }

        //MinInterface implementation
        public string FactoryName
        {
            get{ return _parent._privateName; }//access parent private members
        }
    }
}

public interface MinInterface
{
    string FactoryName{ get; }
}

public interface MyProductInterface : MinInterface
{
    int productID{ get; }
}

public class MyProduct : OuterClass< MyProduct, MyProductInterface >.InnerClass, MyProductInterface
{
    public int productID{ get; private set; }
    static int __nbOfProducts = 0;

    public MyProduct()
    {
        productID = __nbOfProducts;
        __nbOfProducts++;
    }
}

Now it is easy to create a factory of whatever subproduct type and interface:

OuterClass<MyProduct, MyProductInterface> _factory;
_factory = new OuterClass<MyProduct, MyProductInterface>( "Factory");

MyProductInterface _protectedProduct = _factory.GetProduct();
string factoryName = _protectedProduct.FactoryName; 
//interaction with the outer class's private members is limited to the product's base class and minimum interface
//New members and interfaces can be easily derived

Upvotes: 1

Views: 565

Answers (1)

GregRos
GregRos

Reputation: 9113

Please specify the language you're referring to. I assume it's C#.

The pattern you're using makes no sense, when you think about it. OuterClass itself is not a class; OuterClass<T> is a class. In fact, the identifiers used for OuterClass<T> and ΟuterClass by the compiler are different, so you could actually define these two classes in the same file.

Because ΟuterClass itself is not a class, it obviously has no members. However, if you really wanted to, you could do something like this:

public class X : OuterClass<X>.InnerClass
{

}

public class OuterClass<T> where T : OuterClass<T>.InnerClass, new()
{
    public T GetInnerInstance()
    {
        return new T();
    }

    public class InnerClass
    {
        public InnerClass()
        {

        }
    }

}

public class Foo
{
    OuterClass<X> _instance; // yup
}

In order to parameterize OuterClass, you first need to create a type that matches the zany constraint you want. You cannot actually use OuterClass<T>.InnerClass because you first need a type T that matches the constraint T : OuterClass<T>.InnerClass. It sort of becomes a catch 22 type situation. You avoid it by explicitly defining the type.

Upvotes: 1

Related Questions