"Use of unassigned variable" -- work arounds?
Now I've long known and been use to this behavior in C#, and in general, I like it. But sometimes the compiler just isn't smart enough.
I have a small piece of code where right now my workaround isn't a big problem, but it could be in similar cases.
bool gap=false;
DateTime start; // = new DateTime();
for (int i = 0; i < totaldays; i++)
{
if (gap)
{
if (list[i])
{
var whgap = new WorkHistoryGap();
whgap.From = start; //unassigned variable error
whgap.To = dtFrom.AddDays(i);
return whgap;
}
}
else
{
开发者_运维知识库 gap = true;
start = dtFrom.AddDays(i);
}
}
The problem I'm seeing is what if you had to do this with a non-nullable struct that didn't have a default constructor? Would there be anyway to workaround this if start
wasn't a simple DateTime object?
sometimes the compiler just isn't smart enough
The problem you want the compiler to solve is equivalent to the Halting Problem. Since that problem is provably not solvable by computer programs, we make only a minimal attempt to solve it. We don't do anything particularly sophisticated. You're just going to have to live with it.
For more information on why program analysis is equivalent to the Halting Problem, see my article on the subject of deducing whether the end point of a method is reachable. This is essentially the same problem as determining if a variable is definitely assigned; the analysis is very similar.
http://blogs.msdn.com/b/ericlippert/archive/2011/02/24/never-say-never-part-two.aspx
what if you had to do this with a non-nullable struct that didn't have a default constructor?
There is no such animal. All structs, nullable or otherwise, have a default constructor.
Would there be anyway to workaround this if start wasn't a simple DateTime object?
The expression default(T)
gives you the default value for any type T. You can always say
Foo f = default(Foo);
and have a legal assignment. If Foo is a value type then it calls the default constructor, which always exists. If it is a reference type then you get null.
The compiler has no way of knowing that you are guaranteed to set DateTime
because of your gap
variable.
Just use
DateTime start = DateTime.Now;
and be done with it.
Edit Better yet, on second glance through your code, use
DateTime start = dtFrom;
There is no such thing as a default constructor in a struct
. Try it:
struct MyStruct {
public MyStruct() {
// doesn't work
}
}
You can have a static constructor, but you cannot define a default constructor for a struct
. That's why there's the static method Create
on so many structures, and why you can say new Point()
instead of Point.Empty
.
The "default constructor" of any struct
always initializes all of its fields to their default values. The Empty
static field of certian types is for convenience. It actually makes zero difference in performance because they're value types.
Looks to me like your bool gap
and the DateTime start
are really the same thing. Try refactoring like this:
DateTime? gapStart = null ;
for (int i = 0; i < totaldays; i++)
{
if ( gapStart.HasValue )
{
if (list[i])
{
var whgap = new WorkHistoryGap();
whgap.From = gapStart.Value ; //unassigned variable error
whgap.To = dtFrom.AddDays(i);
return whgap;
}
}
else
{
gapStart = dtFrom.AddDays(i);
}
}
[edited to note: please post code samples that will...oh...actually compile. It makes it easier.]
[further edited to note: you set gap to true and set your start
value the first time through the loop. Further refactor to something like this:]
DateTime gapStart = dtFrom.AddDays( 0 );
for ( int i = 1 ; i < totaldays ; i++ )
{
if ( list[i] )
{
var whgap = new WorkHistoryGap();
whgap.From = gapStart.Value; //unassigned variable error
whgap.To = dtFrom.AddDays( i );
return whgap;
}
}
Why are you trying to work around the design of the language? Even if the compiler could work out your entire loop in advance, which seems needlessly complex on the part of the compiler, how does it know that exceptions cannot be thrown in portions of your code? You MUST assign a value to start
because you use it later in the code, possibly before its (according to you) inevitable assignment.
精彩评论