How to Resolve Warning "CS0183: The given expression is always of the provided ('type') type" in C#
The Compiler Warning CS0183 is a Redundancy warning. The message reads: "The given expression is always of the provided ('int') type".
This warning appears when you use the is operator to check the type of a variable, but the compiler determines that the check is unnecessary because the variable's type is already guaranteed to be that specific type (or a derived type) at compile-time. Effectively, you are asking a question to which the answer is always "True" (provided the value is not null).
This guide explains why this check is redundant and how to clean up your code.
Understanding the Redundancy
The is operator is designed to check compatibility at Runtime, typically when dealing with polymorphism (e.g., "Is this generic object actually a string?").
If you write code where the type is known statically:
int x = 10;
if (x is int) { ... }
The compiler knows x is declared as int. An int cannot be anything other than an int. The check will always return true. The compiler flags this to let you know the code serves no logical purpose.
Scenario 1: Checking Value Types
This is the most common cause. You declare a specific value type (like int, double, struct) and then check if it is that type.
Example of warning
public void ProcessId(int id)
{
// ⛔️ Warning CS0183: The given expression is always of the provided ('int') type.
// 'id' is declared as 'int'. It cannot be anything else.
if (id is int)
{
Console.WriteLine("It is a number.");
}
}
Solution: Remove the Check
Since the check is always true, you can simply remove the if wrapper and keep the logic.
public void ProcessId(int id)
{
// ✅ Correct: No check needed.
Console.WriteLine("It is a number.");
}
Nullable Exception:
If the variable were int? (Nullable int), the check if (id is int) would not trigger a warning. In that case, the check effectively means "Is id not null?".
Scenario 2: Checking Inheritance (Upcasting)
In Object-Oriented Programming, a Child class is a Parent class. If you check if a variable of type Child is a Parent, the answer is always yes.
Example of warning
public class Animal { }
public class Dog : Animal { }
public class Program
{
static void Main()
{
Dog myDog = new Dog();
// ⛔️ Warning CS0183: A 'Dog' is always an 'Animal'.
// This check is redundant.
if (myDog is Animal)
{
Console.WriteLine("It is an animal.");
}
}
}
Solution: Remove the Check
If the logic is intended to run for all Dogs, just run it.
public class Program
{
static void Main()
{
Dog myDog = new Dog();
// ✅ Correct: Logic executes unconditionally
Console.WriteLine("It is an animal.");
}
}
Scenario 3: Pattern Matching Redundancy
With modern C# Pattern Matching, developers sometimes try to declare variables inline using checking syntax, even when the type is known.
Example of warning
public void PrintData(string text)
{
// ⛔️ Warning CS0183: 'text' is already known to be a string.
if (text is string s)
{
Console.WriteLine(s.ToUpper());
}
}
Solution: Use is not null or Direct Access
Usually, the developer's intent here is actually to check for null. If text is null, the pattern is string returns false. If that is your goal, use the clearer syntax.
public void PrintData(string text)
{
// ✅ Correct: Explicitly check for null, avoiding the type warning.
if (text is not null)
{
Console.WriteLine(text.ToUpper());
}
}
The expression x is Object is an old-school way of checking x != null. However, modern C# prefers x is not null to avoid CS0183 and improve readability.
Conclusion
CS0183 is a helpful hint to remove clutter.
- Review the Logic: Why are you checking the type?
- If checking for type: The compiler says it's redundant. Remove the
if. - If checking for null: Change the code to
if (variable is not null)orif (variable != null).