tags:

views:

384

answers:

5

Is there a way to cause an error if every constructor doesn't initialize a given member? Maybe something with const?

I want this because I have a pile of code where I'm getting errors as a result of incorrectly computing member values. What I'd really like to do is strip out the whole mess and follow the compiler's lead while redoing it (write code that uses the end result, fix the errors from using non existent code, fix errors from that, etc.). The one step where this doesn't work is member variables because I'm not forced to initialize them in the constructors like I would be for local variables.

+3  A: 

Unfortunately, C# offers no such built-in predicates. The best you can do is write a method that checks the object in question either for nullity or some pre-determined flag value and be disciplined about calling it at the end of each constructor and/or at the top of each method that references the object.

Jekke
+1  A: 

It's supported. For example:

  class Test {
    int notAssigned;
    void method() {
      // Use it, but don't initialize it
      int ix = notAssigned;
    }
  }

Produces:

warning CS0649: Field 'ConsoleApplication1.Test.notAssigned' is never assigned to, and will always have its default value 0

To turn it into an error, use Project + Properties, Build tab, Treat warnings as errors.

Hans Passant
if the members is assigned in a method I think that warning goes away.
BCS
A: 

Tip: In Visual Studio, learn to use Shift + F12 (Find all references). Very handy to find references to those that change state.

leppie
Yup, really hand for some things. But it doesn't find places where a reference is /missing/. <G>
BCS
That's true, kinda tricky situation.
leppie
+1  A: 

I don't think there is a way to have the compiler complain about uninitialized members, provided that the member is initialized in at least one case. But, if you have clear defaults for all values, you could use your default constructor to ensure all members are initialized to their default and inherit the default constructor from all overloaded constructors.

public class Foo
{
   private int val1;
   private List<int> list;

   public Foo()
   {
      //could also be a private constructor if that's appropriate
      //all default initialization
      val1 = 1;
      list = new List<int>();
   }

   public Foo(int nonDefaultValue1) : this()
   {
      //set inputted value
      val1 = nonDefaultValue1;
      //no need to initialize list, done by default constructor
   }
}
Timothy Carter
+1  A: 

sounds like StyleCop can help
of course you must build your custom rule

Avram