【问题标题】:Generic class, constraint by struct, generate compile time error "Use of unassigned local variable"泛型类,结构约束,生成编译时错误“使用未分配的局部变量”
【发布时间】:2026-02-18 02:15:02
【问题描述】:

我有下一个代码:

class GenericStruct<T> where T : struct
{
    public void M()
    {
        T temp1;
        T temp2;
        string s = temp1.ToString();
        Type t = temp1.GetType();
        bool b = temp1.Equals(temp2);
    }
}

调用方法时出现两个错误“使用未分配的局部变量”:ToString 和 Equals,但 GetType 没问题。 “打扰”我是事实,是

where T : struct

但是,如果我写了:

struct NotGenericStruct
{
    public void M()
    {
        NotGenericStruct temp1;
        NotGenericStruct temp2;
        string s = temp1.ToString();
        Type t = temp1.GetType();
        bool b = temp1.Equals(temp2);
    }
}

没问题,编译时没有错误。 我明白了,struct 数据类型有默认构造函数并且所有成员都被初始化,所以不需要写显式的 new。

两种代码之间到底有什么区别?请解释一下我的不理解

谢谢

【问题讨论】:

  • 使用 default(T) 来初始化你的变量
  • @Groo 我不确定它是否重复。如果我理解正确,问题是“有什么区别”而不是“如何解决”。
  • 我同意这不应该真的被关闭。问题是为什么编译器允许在第二个示例中使用未分配的局部变量,当它是一个显式结构时,而不是在第一个示例中,当它是一个隐式结构时。
  • 答案似乎是,如果结构没有字段,则不需要初始化。
  • @Chris:是的,你是对的,你应该发布答案,我重新打开了这个问题。后一个示例没有失败的原因是NotGenericStruct 没有字段,对于通用T : struct 无法保证。

标签: c# generics


【解决方案1】:

在声明中

class GenericStruct<T> where T : struct

struct 表示T 是按值类型。

类型参数必须是值类型。可以指定除Nullable 之外的任何值类型。

所以T 可以是例如int。在这种情况下,声明

T temp1;

使temp1 未初始化。

【讨论】:

    【解决方案2】:

    这两段代码行为不同的原因在于,在一般情况下,我们只知道 T 是一个结构体。除此之外,我们不能再做任何假设。我们不知道结构是否有方法、字段、属性、构造函数或其他任何东西。

    在第二种情况下,我们知道该结构的类型为NotGenericStruct,并且我们知道有关该结构的所有信息。特别是我们可以看到它所拥有的只是一个方法。这意味着我们知道这个对象实际上没有需要初始化的状态。

    我无法引用语言规范中允许这样做的确切部分,但很明显编译器允许一个统一化的结构,因为它知道它与您执行 new NotGenericStruct 时完全一样。

    很容易看出行为上的差异,因为如果您将 int 字段(或任何其他类型)添加到 NotGenericStruct,那么它将立即开始抱怨使用未初始化的局部变量(现在参考 NotGenericStruct有字段)。

    虽然这是一种非常特殊的情况,但通常只适用于没有字段的结构。任何类或任何具有字段 needs 的结构都需要初始化,因此通常最好和最简单的方法是假设 all 局部变量需要初始化。它肯定会产生更易读的代码。

    【讨论】:

      【解决方案3】:

      试试:

      class GenericStruct<T> where T : struct
      {
          public void M()
          {
              T temp1 = default(T);
              T temp2 = default(T);
              string s = temp1.ToString();
              Type t = temp1.GetType();
              bool b = temp1.Equals(temp2);
          }
      }
      

      【讨论】:

        最近更新 更多