A method in a class library which is old or out-of-use and some other method instead of this is suggested to be used.

Generally, when you are introducing some new functionality in your class library but still want to keep an old method intact for some time until the next big release then it’s better to mark that old method as “Obsolete” and offer new functionality in a new method.

Why & when should a method be marked as obsolete?

You are introducing some changes in your class library, and replacing a method with a new one with some added features, at that time it is a good idea to not suddenly remove that method from your class library because it may break some code. But if you mark that method as obsolete then it is an indication that this method is already out-of-use and something else should be used in its place.

Available options in C#

Let’s now see what options are available in C# to mark a method as obsolete.

Open Visual Studio 2015 or 2017 and create a C# class library project named “TestClassLibrary”:

Add a new static class in that project names “TestClass”. Add the following method in that class,

publicstatic string ToUpper(string input) {
return input.ToUpper();
}

Now right click on solution and add a new console application project named “TestConsoleApplication”.

Now we want to indicate to the programmers that instead of “ToUpper” method, they should use “MakeUpperCase” method. Add a message inside “Obsolete” attribute on top of “ToUpper” method:

[Obsolete("This method should not be used, Use MakeUpperCase instead.")]

The whole method will look like,

What have we done here?

We have marked the method with “Obsolete” attribute and added a message to be shown to the user which can work as an indicator to use some other replacement method.

If you now build the project and go to the Main method, you will see a warning with the above message,

Now this looks like a good direction to a programmer who is going to use your class library.

Later, if you think that you have given enough warning and time to programmers using your class library that they should not use this method, and you want to raise an error if they do, then you can convert this warning into error by passing “true” Boolean value after the message:

[Obsolete("This method should not be used, Use MakeUpperCase instead.", true)]

The whole method will look like this,

What have we done here?

We have marked the method with “Obsolete” attribute and added a flag indicating compiler should raise an error if this method is used somewhere.

If you build your project now, it will throw an error,

Use this error flag in your class library when you want to introduce breaking changes in code.

In summary, we have seen the following three overloads of “Obsolete” attribute,

I have attached a sample project with this article, downloaded it and built it one by one by un-commenting only one “Obsolete” attribute at a time,

Note: This article was originally published by me on C# Corner website here.

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. e.g.

var myVal2 = 4294967296L;

var myMoney = 300.5m;

var 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 “object” keywords, use the data type suffix to explicitly state the data type of the value.

In 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.

int

uint

long

ulong

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 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 decimal)

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:

publicstaticvoid TestMethod(int i)
{
Console.WriteLine("You called integer version of TestMethod");
}
publicstaticvoid 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);
TestMethod(5L);
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 to long, hence the TestMethod with long parameter was called.

Now, comment out the above three lines in Main method and write the code given below, followed by clicking F5.