【问题标题】:"Use of unassigned local variable" in a Generic Method通用方法中的“使用未分配的局部变量”
【发布时间】:2011-02-06 09:19:34
【问题描述】:

使用未分配的局部变量“模型”。是我收到的错误消息。它就在我说 if (model == null) 的地方。我不知道为什么它给我一个编译时错误..有人请帮忙。

public static T TryGet<T>(string fileName) where T : new()
{
    T model;
    using (var storageFile = IsolatedStorageFile.GetUserStoreForApplication())
    {
        using (var stream = new IsolatedStorageFileStream(fileName, FileMode.Open, storageFile))
        {
            if (stream.Length > 0)
            {
                var serializer = new DataContractSerializer(typeof(T));
                model = (T)serializer.ReadObject(stream);
            }
        }
    }
    if (model == null)
    {
        model = new T();
    }
    return model;
}

【问题讨论】:

    标签: c# generics


    【解决方案1】:

    正如错误所述,在编译器能够证明它已被赋值之前,您不能使用局部变量。

    在您的情况下,如果您的 if 条件为 false,则永远不会分配 model 变量。

    你可以先给它一个初始值来解决这个问题:

    T model = default(T);
    

    请注意,如果T 是结构类型,则model == null 永远不会为真。

    您应该将代码更改为

    using (var storageFile = IsolatedStorageFile.GetUserStoreForApplication())
    using (var stream = new IsolatedStorageFileStream(fileName, FileMode.Open, storageFile))
    {
        if (stream.Length > 0)
        {
            var serializer = new DataContractSerializer(typeof(T));
            return (T)serializer.ReadObject(stream);
        } 
        else 
        {
            return new T();
        }
    }
    

    【讨论】:

    • 很好的描述性答案。哦——恭喜你:-)
    【解决方案2】:

    在你告诉它之前,编译器不知道要分配什么。

    T model = default(T);代替T model;

    欲了解更多信息:http://msdn.microsoft.com/en-us/library/xwth0h0d(v=vs.80).aspx

    edit:另一种选择是将新语句移动到反序列化块之前。这样,您将拥有一个新对象或反序列化的对象,就像现在一样。

    【讨论】:

    • 这与引用类型无关。此外,T 不是引用类型。
    • @SLaks,我在帖子中没有看到任何暗示 T 不是引用类型的内容。现在的代码仅适用于值类型。对于引用类型,他必须分配 null、default 或新对象。
    • 除非你写where T : class,否则T 不是引用类型。
    • @JimSchubert:值类型和引用类型也会发生同样的错误。实例变量会自动初始化,但局部变量不会。
    • 删除了“引用类型”的注释,因为假设显然是错误的。
    【解决方案3】:

    当使用局部变量时,它们必须在被访问之前被赋值。

    这是因为通常情况下,当开发人员忽略初始化时,他依赖运行时为其分配默认值,但如果他忘记了,这可能会导致一些不必要的错误。

    在使用泛型的情况下,并且没有指定您期望的是ReferenceType 还是ValueType,您不能简单地通过分配null 来初始化它。 在这种情况下,您需要使用default keyword

    这会将变量初始化为null 用于引用类型,或分配0 用于数值类型。对于结构,它会将每个成员初始化为其默认值。

    在您发布的示例中,与null 的比较让我假设此方法可能仅用于ReferenceTypes,如果是这种情况,最好还添加class 约束。

    【讨论】:

    • 我认为在 CLR 中可能没有明确定义的值 until 集(并且 C# 编译器只是采取让编码器执行此操作而不是推动default(T) 某处)——我相信最近看到一个 SO 帖子说变量“插槽”可以通过一些直接字节码访问
    【解决方案4】:

    因为model 是一个局部变量,编译器会给你这个错误,因为它只在 if 语句中赋值。如果 if 语句条件不成立,model 将不会被赋值。尝试给它一个默认值 null 或添加一个 else 语句并在其中分配 model

    T model = null;
    

    局部变量不会自动初始化,但实例变量会。

    public class MyClass<T>
    {
        private T instanceVariable; // automatically initialized
    
        public void MyMethod()
        {
            T localVariable;  // not automatically initialized
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-10-18
      • 2015-11-09
      • 2012-05-18
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多