3

This is a simplified version of what I need to do. In its current state, what I am trying to do doesn't make sense. However it shows the problem in a simple way.

I need to call a function2<T>() where T: TheClass, new() within a function1<T>() where T: class

Something<T> function1<T>() where T : class {
  //cannot call function2 directly due to compile error
  //return function2<T>();

  //What I need as a pseudo code
  if (T is TheClass and T is new())
    return Then function2<T>()
  else
    throw Exception
} 

Something<T> function2<T>() where T : TheClass, new() {
  //...
} 
Nuri Tasdemir
  • 9,720
  • 3
  • 42
  • 67
  • 14
    Since you throw exception anyway if input is not valid - why not apply the same restrictions (TheClass, new()) to function1? – Evk May 17 '16 at 14:33
  • what compiler error are you getting trying to call function2 directly and for what type T? – Marco Fatica May 17 '16 at 14:43
  • @MarcoFatica It doesn't matter what `T` is Since the constraint on `function1` doesn't force it to have a default constructor it can't be used at the parameter for `function2`. – D Stanley May 17 '16 at 14:45
  • Since you want different logic based on what `T` is you're going to have to resort to reflection, or use one method for new-able types and another method for other types. – D Stanley May 17 '16 at 14:46

2 Answers2

2

new() restriction can't be verified at run-time (unlike inheritance where you can use as/is) - so there is no C# construct you can write to invoke function2 from function1 and keep it strongly typed.

Your only option is to construct method via reflection and than call it. See How do I use reflection to call a generic method?

Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
0

You really cannot do that. I'm guessing that function2 is at some point doing new T(), and this might just not be possible for T : class constrained in function1.

You might try for example removing the new() constraint and doing it manually using checks against ConstructorInfo, and get an instance from it as well:

   Type type = typeof(T);
   ConstructorInfo ctor = type.GetConstructor(new Type[0]);
   if(ctor == null) throw new InvalidOperationException();
   object instance = ctor.Invoke(new object[0]);
Gerino
  • 1,943
  • 1
  • 16
  • 21