Introduction
The objectives of this article are
- What is a data type suffix?
- Why is a data type suffix required?
- How and when to use a data type suffix?
What is a data type suffix?
In C#, while specifying any value of a variable or literal, a literal is a source code representation of a value and you can append some specific character after the value/literal, which is called a data type suffix.
long myVal2 = 4294967296L;
decimal myMoney = 300.5m;
float myRadius = 3.145f;
As shown in the above examples, the L, m and f suffixed after the literals are data type suffixes.
For the scope of this article, I will cover the two types of literals given below to which data type suffixes can be applied.
- integer-literal
- real-literal
Why is a data type suffix required?
The data type suffix helps the compiler to unambiguously identify the data type of any value/literal. It also helps C# programmer to explicitly state the data type of the value/literal.
In the cases when a variable is declared, using one of the “var”, “dynamic” or ldquo;object” keywords, use the data type suffix to explicitly state the data type of the value.
In the case of integer literals, if you don't specify any suffix, then the integer values are evaluated to a data type, as per the sequence given below.
In case of real- value literals (those with decimal points or fractions e.g. 3.14), if you don't specify any suffix, then a real- value literal is evaluated to a data type, as per the sequence given below.
- double
- float/decimal (based on suffix)
In short, without any data type suffix, an integer literal will be evaluated to int and real literal will be evaluated to double.
There are data type suffixes given below.
- L or l for a long
- (l in small letters should be avoided as it confuses you with digit 1
- D or d for double
- F or f for float
- M or m for decimal
- (D is already taken for double, so M is best representation for deci mal
- U or u for unsigned integer
- UL or ul for unsigned long
There are no data type suffixes for int, byte, sbyte, short, ushort. Previous versions of C# used to have “Y” and “S” suffixes for byte and short respectively, but they were dropped from C# specification after being found, which are not often used by the programmers.
As a C# programmer, you should be aware of these data type suffixes and make use of them in your programming, so that you won’t have any surprises when your code is executed.
How and when to use a data type suffix?
As stated earlier, you as a programmer do not want C# compiler to decide the data type, as per default specification, then use the data type suffixes.
In the examples given below, I will show the usage in C#. Create a Visual Studio project for C# console Application and in the Program class, create the two methods given below.
public static void TestMethod(int i)
{
Console.WriteLine("You called integer version of TestMethod");
}
public static void TestMethod(long l)
{
Console.WriteLine("You called long version of TestMethod");
}
You must have seen the code given above to create two overloaded methods with the same name “TestMethod” but different int and long arguments. There is not much logic in the method except the message to be written on the console to identify which one was called. You can imagine that there is a specific code here to do different operations for int and long data types.
Now, in Main method, write the two lines of code.
TestMethod(5); // Calls the integer version of TestMethod
TestMethod(5L); // Calls the long version of TestMethod
Console.ReadKey();
You must have noticed two different integer literals passed as parameters to TestMethod.
How does the compiler now decide which method to call?
Press F5 to execute the program. You will see the result given below.
The literal “5” without any suffix got evaluated to int, hence the TestMethod with int parameter was called. The literal “5L” got evaluated too long, hence the TestMethod with long parameter was called.
Now, comment out the above three lines in the Main method and write the code given below, followed by clicking F5.
var myVal1 = 429496; // This should be an int (32-bit)
TestMethod(myVal1);
var myVal2 = 429496L; // This is already a long (64-bit)
TestMethod(myVal2);
You will see the same output as in the previous case due to the same reason.
Now, add the new overload of TestMethod in the Program class given below.
public static void TestMethod(uint i)
{
Console.WriteLine("You called UNSIGNED integer version of TestMethod");
}
In the Main method, write the code given below and click F5.
var myVal3 = 429496u; // This initializes myVal3 as an unsigned integer (uint)
TestMethod(myVal3);
Console.ReadKey();
You will now see the third overloaded method, and the one which you just added will be called.
We will see now the programming in the case of real value literals.
Comment out the above 3 lines, which you just added for unsigned int. In the Program class, create the three new overloaded methods given below.
public static void TestMethod(double i)
{
Console.WriteLine("You called double version of TestMethod");
}
public static void TestMethod(float i)
{
Console.WriteLine("You called float version of TestMethod");
}
public static void TestMethod(decimal i)
{
Console.WriteLine("You called decimal version of TestMethod");
}
In the Main method, write the code given below. Subsequently, click F5 for the execution.
var myVal4 = 9.99; // This initializes myVal4 as a double
TestMethod(myVal4);
var myVal5 = 9999999999999999999999999999m; // This initializes myVal5 as a decimal
TestMethod(myVal5);
var myVal6 = 3.145f; // This initializes myVal6 as a float
TestMethod(myVal6);
Console.ReadKey();
You will see the output given below on the console.
Note here that any real literal (those values with fraction point/decimal) will be evaluated to double by default. Hence, the first call executed the TestMethod with double parameter.
A similar example with dynamic keywords is covered in my attached code, so I am not writing it here.
Let’s see what the compiler says when we use lowercase.
Write the line given below in the Main method, followed by clicking F6 to build the project.
var longTest = 12345L; // Initialize longTest as a long with the value 12345
Go to “Error List” Window and click the Warning header to see the warning.
There is no error but it warns us to use capital L to denote long literal because lower case l can be easily confused with the digit 1.
Please download my attached project, build and run it to play with the examples given above.