tags:

views:

113

answers:

3

Would it be possible to do something like the following in c#? Basically TParent and TChildren should be types of the class A but not necessairly have the same types that were passed in. I know this may sound confusing but I want to strongly type the children and parents of a particular object, but at the same time they must be of the same type. Because TParent inherits from A this would imply that it requires type parameters that inherit from A but using potentially different types.

public class A<TParent, TChildren> 
    where TParent : A
    where TControls : A
{
    TParent Parent;
    List<TChildren> Children;
}

or more easily seen here:

public class A<TParent, TChildren>
    where TParent : A<?, ?>
    where TChildren : A<?, ?>
{
    TParent Parent;
    List<TChildren> Children;
}

I hope this isn't too confusing. Is this at all possible?

Thanks :)

+2  A: 

If you're trying to say "The parent must have this type as a child and the child must have this type as a parent" then I think the answer is no, you can't, because you'd also need to know the type of the parent's parent and the child's child.

However, you can do this

public interface IHasChildren<T>
{
    List<T> Children { get; set; }
}

public interface IHasParent<T>
{
    T Parent { get; set; }
}

public class A<TParent, TChildren> : IHasChildren<TChildren>, IHasParent<TParent>
    where TParent : IHasChildren<A<TParent, TChildren>>
    where TChildren : IHasParent<A<TParent, TChildren>>
{
    public List<TChildren> Children { get; set; }
    public TParent Parent { get; set; }
}
pdr
+2  A: 

No, this isn't possible. The closest you can come is to define another base type, and require TParent and TChild to inherit from that:

public class A { }  // or an interface

public class A<TParent, TChild> : A
  where TParent : A
  where TChild : A
{ }

Which doesn't guarantee you that TParent and TChild are of the generic A<,> type, but does at least allow you to place some constraints on them, which the A<,> implementation can take then assume.

itowlson
A: 

No, this isn't possible. One workaround, however, is to create a subclass of A<TParent, TChild> and enforce that the generic type parameters are of that type:

public interface A
{
   // some properties and methods
}

public class A<TParent, TChild> : A where TParent : A where TChild A
{
   // something else here.  
}
David Morton