---
title: "Overload resolution in C#"
description: "On a recent [LinkedIn Post](https://www.linkedin.com/posts/sa-es-ir_quiz-csharp-overloads-activity-7081218808773820416-2B_s?utm_source=share&utm_medium=member_desktop) from [Saeed Esmaeelinejad](https://www.linkedin.com/in/sa-es-ir/), he asked what is the outcome of:\n\n```csharp\nbool flag = SomeMethod();\n\nM(flag ? 1 : 2);\n\nvoid M(long number) => Console.WriteLine(\"long\");\nvoid M(short number) => Console.WriteLine(\"short\");\n```\n\nWhat is the outcome?"
updated: 2023-07-08
tags: [".NET", "C#"]
canonical: "https://steven-giesel.com/blogPost/3ebbefe2-7db7-4d1d-8d81-719009504027/overload-resolution-in-c"
---

# Overload resolution in C#

On a recent [LinkedIn Post](https://www.linkedin.com/posts/sa-es-ir_quiz-csharp-overloads-activity-7081218808773820416-2B_s?utm_source=share&utm_medium=member_desktop) from [Saeed Esmaeelinejad](https://www.linkedin.com/in/sa-es-ir/), he asked what is the outcome of:

```csharp
bool flag = SomeMethod();

M(flag ? 1 : 2);

void M(long number) => Console.WriteLine("long");
void M(short number) => Console.WriteLine("short");
```

What is the outcome?

## How does overload resolution work in C#?

C# basically checks two things to find a suitable method:
1. Find an exact match for the type of arguments.
2. If it can't find that, try to find a match with implicit conversions

In the case of Saeed's question, the first step fails, because the type of the argument is `int`, and there is no method with an `int` argument. So the second step is tried, and there is an implicit conversion from `int` to `long` and `short`. So both methods are applicable. But which one is better?

The answer here is simple: Imagine the number `300000`. This number can be converted to a `long` without any loss of information, but it can't be converted to a `short` without losing information. So the `long` method is better, and that is the one that is called. So the answer for Saeed's question is `long`.

But wait, we are not done here! Let's change the code a little bit:

```csharp
const int a = 1;

M(a);

void M(long number) => Console.WriteLine("long");
void M(short number) => Console.WriteLine("short");
```

What is now the outcome? Well the picture shifts: Now the `short` method is better, because the number `1` can be converted to a `short` without losing information, and the compiler can determine this at compile time as `a` can never change! We can also take this one step further:

```csharp
const int a = 1234567;
var b = 1;

M(a);
M(b);
```

In both cases, we get `long` as the answer. Huhh? Why? Well, the compiler can't determine the value of `b` at compile time, so it can't determine if the conversion from `int` to `short` will lose information. So it has to assume that it will lose information, and therefore the `long` method is better.

Let's consider a last example that might seem surprising:

```csharp
var flag = false;
M(flag switch { true => 1, false => 2 });
```

What do you think is the outcome, `short` or `long`? Surprisingly it is `short` in contrast to the initial question. Why is that? Well, `switch` expressions are different than the ternary operator as `switch` statements are determined at compile-time. So the possible outcomes are known in advance here.

## While we are at it
Going away from the original question, I have some more interesting parts for you. Have a look at the following code sample:

```csharp
void M(int number) => Console.WriteLine("int");
void M(int number, int anotherNumber = 0) => Console.WriteLine("int with optional");

M(1);
```

If we call `M(1)`, both methods seem to be suitable, but in this case, the one without the optional parameter is prioritized over the one with. Therefore we print out *"int"* to the console.

One last example to finish the topic:
```csharp
void M(object o) => Console.WriteLine("object");
void M(double d) => Console.WriteLine("double");
void M(float f) => Console.WriteLine("float");

M(5);
```

The answer might be surprising: It's `float` as result. You can see this on [sharplab.io](https://sharplab.io/#v2:D4AQTAjAsAUL4GZYG9YAINvGdnU00LQFkAKAVgEoBuXDAXzrSZASwgDYsAWE0gewBGAKwCmAYwAuafpTQBeAHzsAnKQBEQsVPU0WbEJx58AJvwCuggDai0JuUtUazlm7toFMrdlxC8yAGZW/ACG0gEOyoZq6kGhku6w9EA==) in action. In this example, you can see that the lowered code is `M(5f);`, so the compiler decided that `float` is the most precise type. That makes sense as it "occupies" the same memory space and still is able to represent the number.

## Conclusion
Overload resolution in C# can be fun! At least, I liked the small riddle of Saeed a lot and it led me to dig into some C# code specifications to understand the behavior of the language!