“使用未分配的变量” - 解决方法?

时间:2011-07-06 20:17:22

标签: c# .net struct compiler-errors

现在我早就知道并且习惯于在C#中使用这种行为,一般来说,我喜欢它。但有时编译器不够智能。

我有一小段代码,现在我的解决方法不是一个大问题,但可能是类似的情况。

        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);
            }
        }

我遇到的问题是,如果你必须使用没有默认构造函数的非可空结构来执行此操作?如果start不是简单的DateTime对象,那么还是可以解决这个问题吗?

5 个答案:

答案 0 :(得分:10)

  

有时编译器不够智能

您希望编译器解决的问题等同于暂停问题。由于计算机程序无法解决该问题,因此我们只做了最小的尝试来解决它。我们没有做任何特别复杂的事情。你将不得不忍受它。

有关为什么程序分析等同于暂停问题的更多信息,请参阅我的文章,该文章主题是推断方法的终点是否可达。这与确定变量是否明确分配的问题基本相同;分析非常相似。

http://blogs.msdn.com/b/ericlippert/archive/2011/02/24/never-say-never-part-two.aspx

  

如果必须使用没有默认构造函数的非可空结构来执行此操作,该怎么办?

没有这样的动物。所有结构,可以为空或以其他方式具有默认构造函数。

  

如果start不是一个简单的DateTime对象,还是可以解决这个问题吗?

表达式default(T)为您提供任何类型T的默认值。您可以随时说

Foo f = default(Foo);

并有法律任务。如果Foo是值类型,则它调用默认构造函数,该构造函数始终存在。如果它是引用类型,那么您将获得null。

答案 1 :(得分:6)

由于您的DateTime变量,编译器无法确定您是否可以设置gap

只需使用

DateTime start = DateTime.Now;

并完成它。

修改更好的是,第二眼看看您的代码,请使用

DateTime start = dtFrom;

答案 2 :(得分:4)

struct中没有默认构造函数。试试吧:

struct MyStruct {
    public MyStruct() {
        // doesn't work
    }
}

您可以拥有静态构造函数,但无法为struct定义默认构造函数。这就是为什么在这么多结构上有静态方法Create的原因,以及为什么你可以说new Point()而不是Point.Empty

任何struct的“默认构造函数”始终将其所有字段初始化为其默认值。 certian类型的Empty静态字段是为了方便起见。它实际上在性能上没有差别,因为它们是值类型。

答案 3 :(得分:3)

在我看来,你的bool gap和DateTime start实际上是一回事。尝试这样的重构:

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);
    }
}

[编辑注意:请发布代码样本......哦...实际编译。它使它更容易。]

[进一步编辑注意:您将gap设置为true并在循环中第一次设置start值。进一步重构这样的事情:]

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;
  }
}

答案 4 :(得分:1)

为什么要尝试解决语言设计问题?即使编译器可以提前计算出你的整个循环,这在编译器方面似乎是不必要的复杂,它如何知道不能在代码的某些部分抛出异常?您必须为start分配一个值,因为您稍后会在代码中使用它,可能在它(根据您)不可避免的分配之前使用它。