C# 当当前项目中的等效结构不是';时,为什么可以访问单独项目提供的未初始化结构;T 如果结构没有字段,则无需初始化即可访问它 如果当前项目中的结构具有字段,则会出现错误“使用未分配的局部变量” 如果不同项目中的结构具有字段,则无需初始化即可访问该字段

C# 当当前项目中的等效结构不是';时,为什么可以访问单独项目提供的未初始化结构;T 如果结构没有字段,则无需初始化即可访问它 如果当前项目中的结构具有字段,则会出现错误“使用未分配的局部变量” 如果不同项目中的结构具有字段,则无需初始化即可访问该字段,c#,struct,initialization,C#,Struct,Initialization,这种行为似乎奇怪地前后矛盾。使用不同项目中的字段访问未初始化的结构不会导致错误,但如果在同一项目中声明,则会导致错误,原因是什么?语言规范解决了这个问题吗 下面是一些演示各种场景的示例代码 项目1 static void Main() { A A; a、 ToString();//没问题 B B; b、 ToString();//使用未分配的局部变量“b” C C; c、 ToString();//没问题 } 公共结构A { } 公共结构B { T[]a; } 项目2 public结构 { T

这种行为似乎奇怪地前后矛盾。使用不同项目中的字段访问未初始化的结构不会导致错误,但如果在同一项目中声明,则会导致错误,原因是什么?语言规范解决了这个问题吗

下面是一些演示各种场景的示例代码

项目1
static void Main()
{
A A;
a、 ToString();//没问题
B B;
b、 ToString();//使用未分配的局部变量“b”
C C;
c、 ToString();//没问题
}
公共结构A
{
}
公共结构B
{
T[]a;
}
项目2
public结构
{
T[]a;
}

(使用VS2017 15.4.5)

这是编译器作者有意做出的决定,以保持与不符合规范的旧编译器的向后兼容性。您可以在编译时使用
/features:strict
标志获得正确的行为

见:

这是一个非常痛苦但有意的决定。这将复制上一个编译器的(错误)行为。我强烈建议您添加编译器标志/特性:strict,以获得正确的规范要求(但不向后兼容)行为


我不知道规范中是否有提到它的部分,但这是一些有趣的阅读。基本上,我们倾向于将私有字段视为实现,而不是接口,但C#中的明确赋值规则要求将结构的私有字段视为其接口的一部分。在某种程度上是绝对相关的。但是引用程序集和我的示例之间的区别在于
project2
不是引用程序集。这是一个正确的程序集,从技术上讲,所有这些私有字段都以某种方式在程序集中(即反射将返回它们),是的,这是一个区别。这这似乎是为了向后兼容旧版本的编译器。@mikez这是一个很好的链接。使用
strict
标志实际上解决了我的根本问题。如果你把它作为一个答案发布(可能直接包含那个标志),你会马上接受它。很好,可能会添加一点关于
strict
的内容,这样你就会得到你想要的编译器错误。但是+1,谢谢!相关地:
static void Main()
{
    A a;
    a.ToString();    // No problem

    B<int> b;
    b.ToString();    // Use of unassigned local variable 'b'

    C<int> c;
    c.ToString();    // No problem
}

public struct A 
{
}

public struct B<T> 
{
    T[] a;
}
public struct C<T>
{
    T[] a;
}