Archive

Posts Tagged ‘coding’

Common warnings in C#: Cause, effect and resolution

June 29th, 2008 Bobby Alexander 1 comment

Ah, warnings. Those little indicators that we constantly ignore. Lets sweep them under the carpet and carry on with our lives. I mean, they are just warnings right? Not as if you are going to break something if you don’t fix it right? It’s like smoking, some people pay the price, some get away with it. The Doctor warns you all the same.

Its the same in coding, the warnings are there for exactly that: to warn you that you may screw up down the line somewhere or probably face undesirable side effects. Application crashes anybody?

In this edition I shall list some of the common warnings you will encounter, its reason and solution.

Note: The framework considered is 2.0

Field ‘field name‘ is never assigned to, and will always have its default value null – You declared a class member variable but never used it. Check why. If not required, remove the member.

The variable ‘variable name’ is declared but never used – You declared a variable in a scope but it was never used. Check why. If it is no longer required, remove it.

The variable ‘variable name’ is assigned but its value is never used – You declared a variable and assigned a value to it. But the variable was never used in the specified scope. Check why. If not required, remove it.

The private field ‘field name’ is never used – Same reason as above.

Note: The compiler checks whether variables that have been declared have ever been used on the right hand side of an expression or as an out parameter to a method. If not, the compiler generates a variable not used’ warning. Unused variables add to the clutter and makes code confusing and difficult to read. Check the variable in question and remove it if its not required.

member1‘ hides inherited member ‘member2‘. Use the new keyword if hiding was intended – You declared a member in a derived class that has the same name as a member in the base class. If you really intended to hide the base class member use the new modifier before the member declaration. Even if you don’t explicitly use the new keyword, the compiler adds it anyway. Why is this a warning, you may ask. Well, you may have unknowingly declared a member with the same name. This warning acts a heads up. Explicitly adding the new keyword tells the compiler that you were aware of the member in the base class and you intended to hide it.

function 1‘ hides inherited member ‘function 2‘. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword - I would have preferred if this was thrown as an error than just a warning. This warning show a flaw in design or outright lack of understanding.

Lets understand this warning with an example:

public class Base{   public virtual void DoSomeWork()   {       Console.WriteLine("Base called");   }}public class Derived: Base{   //Did you mean this method to override    //the base class method   //or is it just another method    //having the same base class name?   public void DoSomeWork()    //Warning!   {       Console.WriteLine("Derived called");   }}

Note that the base class method is virtual. This means that the Derived class can supercede the implementation with its own method with the same name and signature.

As my comment says, the derived class method’s name might have been unintended (like the previous warning). For all you care the derived class method might have been called TrimTheHedge or something like that. In that the warning gives you a chance of changing the method name (for clarity’s sake). If you really want the method to be called DoSomeWork (because you have a penchant for abstract looking names) then add the new modifier to it to tell the compiler that the derived class method WAS NOT written to override the base class’s virtual method. If you really meant to override the base class method, use the override keyword in the derived class method.

Again, why? Lets say, the intention of the derived class method was indeed to override the base class method, which works perfectly fine in the example above. Now you decide to change the base class methods signature by adding a parameter to the method, say a string.

public virtual void DoSomeWork(string mystring){      Console.WriteLine("Base called with "                        + mystring);}

This means that your derived class methods signature also should be modified (since it is supposed to override the base class method and hence the signatures are supposed to match). If you are one of those few people who keep track of all the classes that derived from a particular class then you could possibly find all the overridden methods and change their signature. What if you miss a method? Would it give an error? (which is what you would expect). Well, unfortunately it wont. The compiler just thinks that you intended to hide the method and implicitly adds the new modifier to that method you forgot to modify and life goes on as usual till the day arrives when your application uses that method and the output didn’t turn out quite what you expected. (In the above example you would get "Derived called" instead of "Derived called with Take Out The Trash", assuming you pass "Take out the trash" as the parameter)

To ensure that you get an error when this happens, add the override keyword after public.

public override void DoSomeWork()    //Error{ Console.WriteLine("Derived called with "                    + mystring);}

Error: ‘Derived.DoSomeWork()’: no suitable method found to override

Now you will realize that you have missed out a method and make the required changes.

Some warning, huh?

Possible unintended reference comparison; to get a value comparison, cast the left hand side to type ‘type‘ – Look ma, no cast.

class is obsolete:’class name 1 ‘This class has been deprecated. Please use ‘class name 2‘ instead – The specified framework class/type is no longer supported. The class may have been reworked to improve performance or may have been enhanced and/or moved to a different namespace or may have been renamed. The warning specifies the alternative type to use.

Unreachable code detected – The compiler has detected that the specified code block will never be executed. Check if this is expected. This is usually caused due to a misplaced return statement or a conditional block that will never be true. Another common scenario is putting a return statement inside a case block of a switch…case statement. In this case the break statement following the case block is marked as unreachable. Demonstrates shoddy programming.

int i = 0;

CheckValidity(i);

AppendToLog(i);

return;

i++; //Unreachable code!

 

bool isValid = false;

if (isValid)

{

//This block is unreachable because isValid is never true!

int i=0;

CheckValidity(i);

}

Accessing a member on ‘member’ may cause a runtime exception because it is a field of a marshal-by-reference class – This will take an article in itself but I’ll try to keep it short for your sanity’s sake. An application in one App domain can access objects in other app domains in two ways. One is by copying the entire object over to the other side and the other is by setting up a proxy. The app domain that needs to communicate with the object makes calls to the proxy which in turn are routed to the actual object on the other App domain. Classes that derive from MarshalByRefObject class communicate by using proxies.

Now, why would you want to do that? Well if you design a class that has members that are unusable outside the app domain on which it was created you would derive from MarshalByRefObject. (System.Windows.Forms.Form is one such class and most of such warnings originate from your forms). A subtle piece of information that the warning message leaves out (but mentioned in MSDN) is that the warning occurs only if the member you are trying to access in a value type.

When you try to operate directly on a value type across app domains say by calling a method on it, an attempt is made to calculate the address of the member in the remote app domain which is illegal and will fail. Do note that if the member was a reference type there would be no warning (due to the virtue of it being a reference type).

Lets look at the MSDN example as it is short and simple:

class WarningCS1690: MarshalByRefObject{  int i = 5;

  public static void Main()  {    WarningCS1690 e = new WarningCS1690();    e.i.ToString();   // CS1690

    // OK    int i = e.i;    i.ToString();    e.i = i;  }}

As you can see an attempt is being made to operate on the value type ‘i’ directly by calling the ToString() method on it.

The recommended practice is to first copy the member in question to a local variable and then to call the method on it as shown in the latter part of the code.

Why should you be bothered? If the class that derives from MarshalByRefObject is ever used across app domains and an attempt is made to access a member as mentioned, then your application will throw an InvalidOperationException and if not handled, will crash. If your class will NEVER be accessed across app domains then you can safely ignore this warning but I suggest that you code it as mentioned to prevent future headaches.

Assignment made to same variable; did you mean to assign something else? – You did something silly like this: myValue = myValue; Were you trying to do something else?

Well, there you have it; the most common warnings you will encounter in C#. This list may vary a bit depending on the type and complexity of your project. So if you encounter a warning you cant make head or tail of, drop me a line and I’ll try to add it to this article. All the best for your very own 0 errors, 0 warnings.

Code safely,

Alex

Categories: Uncategorized Tags: ,