简体   繁体   English

通过C#中的Action传递结构体无法编译

[英]Passing a struct via an Action in C# does not compile

I have a code which works and compiles perfectly, where I have an Action defined as: 我有一个可以正常工作和编译的代码,其中的Action定义为:

Action<double, double, double ....> OnBlah;

Now I have more than 16 params, so I want to pass a struct instead, so I defined the action as: 现在我有16个以上的参数,因此我想传递一个结构,因此将操作定义为:

Action<structName> OnBlah;

But I get an error in the C# compiler that says that structName is not initialized. 但是我在C#编译器中收到一条错误消息,提示未初始化structName。 This is weird since: 这很奇怪,因为:

A. Previously in the code I passed the double parameters for OnBlah from the struct directly. 答:以前在代码中,我直接从结构传递了OnBlah的double参数。

B. Structs are initialized by definition. B.结构通过定义初始化。

I'm using VS 2010, I'm guessing this is a compiler bug ? 我正在使用VS 2010,我猜这是编译器错误吗?

Added reproduction code for the compiler bug: 为编译器错误添加了复制代码:

namespace CompilerBug
{
    struct Test
    {
        public double a;
    }

    class Program
    {
        static Action<Test> OnBlah;

        static void DoesCompileOk()
        {
            Test test;
            test.a = 5;
            OnBlah(test);
        }

        static void DoesNotCompileOk()
        {
            Test test;
            int b = 0;
            if (b == 4)
            {
                test.a = 5;
            }
            OnBlah(test);
        }

        static void Main(string[] args)
        {
            OnBlah = (t) => { };
        }
    }
}

This is not a compiler bug. 这不是编译器错误。 You need to initialize the struct first, like the compiler says. 您需要先初始化结构,如编译器所说。 Presumably your error is actually in the code which invokes the delegate since nothing else makes sense. 大概您的错误实际上在调用委托的代码中,因为没有其他意义。

When you were invoking the delegate with your 16 parameter double version, the double parameters were initialized. 当您使用16参数double版本调用委托时,double参数已初始化。 If you had not initialized them, then the compiler would have emitted the same error. 如果尚未初始化它们,则编译器将发出相同的错误。 For example: 例如:

private static void actDouble(double d)
{
}

static void Main(string[] args)
{
    double d;
    Action<double> act = actDouble;
    act(d);//error on this line
}

This fails to compile with the following error: 无法编译,并出现以下错误:

error CS0165: Use of unassigned local variable 'd'

There is nothing special about structs in this regard. 在这方面,结构没有什么特别的。

As a general rule, your first guess when you encounter a syntax error should never be that this is a compiler bug. 通常,遇到语法错误时,您的第一个猜测永远不应是这是编译器错误。 Compiler bugs are exceedingly rare, especially in a compiler as widely used as this one. 编译器错误极为罕见,尤其是在像这样广泛使用的编译器中。


Update following the edit to the question which added real code 在对添加了真实代码的问题进行编辑之后进行更新

Test test;
int b = 0;
if (b == 4)
{
    test.a = 5;
}
OnBlah(test);

The compiler is not sure that test is fully initialized. 编译器不确定test是否已完全初始化。 It does not do program flow analysis. 它不执行程序流分析。 You can fix the problem by making sure that the compiler knows that the struct is fully initialized. 您可以通过确保编译器知道该结构已完全初始化来解决此问题。

Action<structName> OnBlah;

can never raise the error you cite; 永远不会提出您引用的错误; if either of the two types Action or structName can't be resolved, it'll complain - and if the generic type argument isn't suitable it'll complain, but that is expected. 如果无法解析ActionstructName这两种类型中的任何一种,则会抱怨-如果通用类型参数不合适,则会抱怨,但这是预期的。

If OnBlah is a field it is automatically initialized to null; 如果OnBlah是一个字段,它将自动初始化为null;否则,它将自动初始化为null。 if it is a variable it will need to be assigned before use. 如果是变量 ,则需要在使用前进行分配。 It could be assigned to null , but if so it will fail at runtime when you try to invoke it (unless you do a null-check). 可以将其分配为null ,但是如果是这样,则在尝试调用它时会在运行时失败(除非您执行null检查)。 So then we come to invoke; 于是我们来调用; if we assume non-null, you need to supply an argument, ie 如果我们假设非空,则需要提供一个参数,即

OnBlah(someValue); // or OnBlah.Invoke(someValue);

here, if someValue has not been defined it will error; 在这里,如果未定义 someValue ,则会出错; it if is not definitely assigned it will error. 如果未明确分配 ,它将出错。 For definite assignment, fields are assigned; 对于确定的分配,将分配字段 variables are not unless initialized. 除非初始化,否则不会变量。

In the case of structs, a value is initialized either by using the constructor (or another method that returns the value), or by manually setting every field (which shouldn't be possible, since a: structs should be immutable, and b: fields should be private). 在结构中的情况下,一个值是由使用构造(或返回值的另一种方法) 或者初始化, 通过手动设置场(这不应该是可能的,因为一个:结构应该是不可变的,和b:字段应为私有)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM