5

I have a generic class. The constructor needs to accept an argument that is another instance of the same class. The problem is that the other instance can have a different generics type.

Looks like C# allows me to have a method with it's own generics type, but this doesn't appear allowed for the constructor.

public class MyClass<T>
{
    public MyClass<T2>(MyClass<T2> parent = null)
    {
    }

    // ... Additional stuff
}

The code above tells me T2 is undefined. It doesn't accept it as a method type.

One approach would be to add a second generic type to my class. But this is awkward and, in many cases, the argument will be null and there is not type.

Does anyone see a simple way around this?

6
  • 2
    maybe public class MyClass<T, T2> Commented Aug 28, 2016 at 22:33
  • What is it your trying to do by creating this class? Commented Aug 28, 2016 at 22:35
  • @Slai I was thinking that as well but that lead to a cycle I couldn't seem to break out of. lol Commented Aug 28, 2016 at 22:36
  • 1
    @jdphenix: Sorry, I don't see the relevance of that. I'm not new to programming and I have a hundred ways I could write this. But the way I'd like to write it best requires the technique described in my question. Commented Aug 28, 2016 at 22:54
  • 3
    Right - well, then I really don't see how your question isn't really just an XY problem. I'm also not sure what my question has to do with your experience or familiarity with ways to implement whatever it is you're doing. Commented Aug 28, 2016 at 23:07

2 Answers 2

5

Generic constructors aren't allowed. However, you can use a generic factory method instead.

public class MyClass<T>
{
    public int Id { get; private set; }
    public int? ParentId { get; private set; }

    public static MyClass<T> Create(int id)
    {
        return Create<object>(id, null);
    }

    public static MyClass<T> Create<T2>(int id, MyClass<T2> parent = null)
    {
        var current = new MyClass<T>();
        current.Id = id;
        current.ParentId = parent?.Id;
        return current;
    }

    private MyClass()
    {
    }

    // ... Additional stuff
}

Sample use:

var intClass = MyClass<int>.Create(55);
var charClass = MyClass<char>.Create(234, intClass);
// charClass.ParentId is 55

This is only possible if you do not need to access any generic members of parent outside the factory method. If you do, you'd be better off abstracting it through a non-generic interface or base class.

Sign up to request clarification or add additional context in comments.

2 Comments

This gives error public static MyClass<T> Create<T2>(int id, MyClass<T2> parent = null)
@AliKaraca: What error is it giving you? It works for me: ideone.com/KQOuMb
4

You are correct. Generic constructors aren't supported.

You could probably try the following:

Create a lower level common interface

public interface IMyClass {
    //...some common stuff
    IMyClass Parent { get; set; }
}

And use that as the common link between the types

public class MyClass<T> : IMyClass {
    public MyClass(IMyClass parent = null) {
        Parent = parent;
    }
    public IMyClass Parent { get; set; }    
    // ... Additional stuff
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.