2

I have such an example code:

static void Main()
{
    dynamic dynamicObject = null;
    object simpleObject = dynamicObject + new AnyClass();
    Console.WriteLine(simpleObject);
}

class AnyClass
{
    public override string ToString()
    {
        return "text";
    }
}

Execution result is:

text

If I understood it correctly, then part dynamicObject + new AnyClass() calls the string concatenation, which return empty string for dynamicObject due to it refers to null, and new AnyClass() returns text. But there's no string argument, which is necessary to call ToString(). Why does it happens so? Why is an exception not being generated about the lack of implementation of the operation '+'?

9
  • "there's no string argument, which is necessary to call ToString()" - what string argument? Commented Feb 19, 2024 at 12:48
  • @Fildor I assume they mean that there is nothing obvious to force the object to execute ToString. Like "hello " + new AnyClass(). Commented Feb 19, 2024 at 12:53
  • @SMSTJ That's why I am asking. So we don't have to assume :D Commented Feb 19, 2024 at 12:56
  • @Fildor I know when type of at least one argument of '+' operation is a 'string' then invokes ToString() for the second argument, but here no arguments of string type and in spite of it, ToString() called for each Commented Feb 19, 2024 at 12:57
  • 1
    Interesting thing is that it will even do this if you just do: null + new AnyClass(); Commented Feb 19, 2024 at 13:01

1 Answer 1

3

This is just a matter of operator overload resolution. Since neither null nor AnyClass declare any user-defined operators, the built-in overloads of + are considered. Here is a non-exhaustive list.

string operator +(string x, string y);
string operator +(string x, object y);
string operator +(object x, string y);
decimal operator +(decimal x, decimal y);
int operator +(int x, int y);
long operator +(long x, long y);
float operator +(float x, float y);
double operator +(double x, double y);

Since the second parameter is an instance of AnyClass, everything that doesn't take an AnyClass as a second parameter is eliminated, and we are left with:

string operator +(string x, object y);

Therefore, this is the operator that is called.

Of course, the results would be different if you declared your own + operators.

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

5 Comments

So, in my view this would make the code in question really brittle, won't it? Having the dynamic var always null doesn't make sense, so I think it's safe to assume there will be cases where it's not. Which in turn means, that a different overload that does not do the same as this one could (or even will) be chosen ... right?
@Fildor Yeah, IMO that's the nature of dynamic-typed code.
Now that I read it, yeah that makes sense. Brittle by design.
All of the value-type operators are lifted, so null does not in fact exclude any of the value type operands. AnyClass not being convertible to any of them is what excludes them.
@Servy Thanks. I forgot about lifted operators.

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.