15
class CustomClass<T> where T: bool
{
    public CustomClass(T defaultValue)
    {
        init(defaultValue); // why can't the compiler just use void init(bool) here?
    }
    public void init(bool defaultValue)
    {

    }
    // public void init(int defaultValue) will be implemented later
}

Hello. This seems to be a simple question, but I couldn't find an answer on the Internet: Why won't the compiler use the init method? I simply want to provide different methods for different types.

Instead it prints the following error message: "The best overloaded method match for 'CustomClass.init(bool)' has some invalid arguments"

I would be glad about a hint.

Best regards, Chris

11
  • 3
    Why aren't you using public void init(T defaultValue) ? Commented Oct 10, 2010 at 22:33
  • 6
    The compiler should complain much earlier: You can't do where T: bool. Commented Oct 10, 2010 at 22:34
  • 2
    What's the point of this?? Boolean is a sealed class and cannot be inherited from. So your T can only be a boolean. Commented Oct 10, 2010 at 22:41
  • 2
    @Chris, not sure what you're trying to achieve. The compiler is telling you that T != bool and there is no appropriate conversion from T to bool. I suspect that you do not have behaviours that are the same across multiple types and therefore a generic class is not the best solution. Have you thought about an interface (or base class) with implementations (or subclasses) for different types? Why are you trying to use a generic here? What is the problem you are trying to solve? Commented Oct 10, 2010 at 22:43
  • 1
    @Chris ~ then in the class constructor instead of just calling init(bool) test it for if (T is bool) init(bool) Commented Oct 10, 2010 at 23:20

1 Answer 1

38

The compiler cannot use init(bool) because at compile-time it cannot know that T is bool. What you are asking for is dynamic dispatch — which method is actually being called depends on the run-time type of the argument and cannot be determined at compile-time.

You can achieve this in C# 4.0 by using the dynamic type:

class CustomClass<T>
{
    public CustomClass(T defaultValue)
    {
        init((dynamic)defaultValue);
    }
    private void init(bool defaultValue) { Console.WriteLine("bool"); }
    private void init(int defaultValue) { Console.WriteLine("int"); }
    private void init(object defaultValue) {
        Console.WriteLine("fallback for all other types that don’t have "+
                          "a more specific init()");
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

+1, This does appear to be what the OP is trying to get at. Also, interesting use of dynamic. I've occasionally wanted to use the switch statement with types and this seems like an interesting way of simulating the effect.
Thank you very much for your quick reply. In my opinion it was possible to decide at compile time because the constructor calls with bool already existed in the program. The dynamic keyword is a nice feature. How would I solve this using C# 3.5?
@Chris: Just because you call the constructor with a bool doesn’t mean the compiler can emit a call to init(bool). You could call the same constructor with a different type argument from another assembly later! — Unfortunately, my solution only works with C# 4.0 and up. There is no C# 3.5. If you need to use C# 3.0 (or perhaps you mean .NET 3.5?) then your only option is to use a series of if ((object)defaultValue is bool) ... else ....
Right I mean .NET 3.5. Thank you very much for your support.
Thank you. As a c++ programmer the problem was a surprise when I came across it just now (while writing my app). Your answer is simple and elegant. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.