Type-inferring a constant in C#

后端 未结 11 1131
花落未央
花落未央 2020-12-05 13:14

In C#, the following type-inference works:

var s = \"abcd\";

But why can\'t the type be inferred when the variable is a constant?

T

相关标签:
11条回答
  • 2020-12-05 13:32

    In this case it is obvious that you know the reference type will be constant, and of a fairly primitive type (consts can only be value types, or strings, etc..), so you should declare that type, rather than use implicit typing.

    In other words, because the type is obviously constant and known, there's absolutely no reason to use var.

    Implicitly typed local variables are only necessary for storing anonymous types. In all other cases they are just a convenience. If the value of the variable never changes, just give it an explicit type. Attempting to use the readonly modifier with an implicitly typed local will generate CS0106.

    http://msdn.microsoft.com/en-us/library/bb310881.aspx

    Compiler Error CS0822

    To correct this error If you require the variable to be constant or readonly, give it an explicit type.

    0 讨论(0)
  • 2020-12-05 13:35

    My answer? Since it is not currently possible to use "const var" don't even worry about it. That limitation, for no reason at all, makes C# unbalanced in how it treats constants versus variables and that creates an assymetry. You'd be better off

    "The "var" syntax was chosen to call out "this is a variable", and we're sticking with it."

    I find Eric Lippert's arguemnt deeply unconvincing on multiple levels.

    Eric, I don't know who "we" are and I really don't want to sound rude but both the use (as in the reason for being) AND meaning (as in why var is appropriate name) have nothing to do with the meaning you are trying to attach to it. "Var" is used it place of an an explicit type declaration and signifies the fact that it's type, at that point in time, can be one of many.

    To recap, var replaces the type declaration. Let's not pretend that it does anything else because type and value (and whether or not this value can be changed) are two distinct things. Occum's razor applies here and there is no need to expand the meaning of var beyond what it does.

    More importantly, even in the days when implicit declarations were not an option and the var keyword was in use people still thought of their objects as variables and had no problem declaring their variables as constants.

    "var" was introduced because there was a need for it. And that need was not to make variables safe from becoming constants. That limited interpritation creates another need, that is currently not meet.

    Your whole stance can be deduced to a symantics argument - we simply don't like the way "const var sounds" (e.g. "gives me the shudders to type.") This is odd considering that one can type something like "dynamic static" without compilation errors and that sounds awkward too.

    Sp why emphasize something that has absolutely no risk of being ambigious in the first place? Is "const var = "Hello World"" or some variation of thereof really going to make people puzzled weather it's a constant or not. I think people will be able to understand exactly what that means, just as they understand what "dynamic static" means.

    The real bottom line is that being able to implicitly declare constants both makes sense and can actually be useful. There is currently no way to do that for seemingly no reason. And it makes a heck of a lot more sense to be able to declare "const var" than to introduce yet another keyword to serve implicitly declared constants.

    And if you don't think that Eric's argument is entirely based on needlessly complex interpretation of semantics, try to build the same argument around the meaning of "var" if it's called by a different name. Say, impl. Would there be any reason why impl couldn't be used in conjunction with const? I'd be hard pressed to come up with a single reason for it. Therefore, it comes down to not liking the way "const var" sounds and nothing else. I think most of us could easily get over that.

    0 讨论(0)
  • 2020-12-05 13:36

    I agree with Eric that this is ugly as sin:

    const var s = "abcd"

    But why not simply this?

    const s = "abcd"

    Seems like a reasonable syntax to me.

    0 讨论(0)
  • 2020-12-05 13:45

    I realized that what I (we) actually wanted is the behavior of the const keyword as defined in JavaScript or C. That is, the ability to calculate it at runtime but disallow updating it in subsequent code. This can be useful to force discipline and be explicit when you only want a value to be calculated once.

    In other words, what this question is really asking for is to be able to use the readonly keyword on locals (variables/method parameters). I.e., this syntax might be useful:

    // This variable should never be overwritten!
    readonly var target = 4;
    

    It is not like there is no precedent for this in C#. using() and iteration (foreach) variables already behave this way:

    class Program
    {
        static void Main(string[] args)
        {
            foreach (var x in new[] { "asdf", })
            {
                System.Console.WriteLine(x);
                // error CS1656: Cannot assign to 'x' because it is a 'foreach iteration variable'
                x = "food";
            }
        }
    }
    

    Oh, look—I got type inference and readonly behavior! Yay! However, using the foreach keyword is way too clunky to actually do this in real code. It is not obvious at all that you’re trying to protect yourself from, uh, yourself or your coworkers adding code that mutates x later without thinking through the implications (with the help of a compiler error). That is why it would be great if it became a language feature.

    0 讨论(0)
  • 2020-12-05 13:50

    The short answer is because the language designers (Microsoft) say so.

    From MSDN:

    Compiler Error CS0822

    Error Message: Implicitly typed locals cannot be const

    Implicitly typed local variables are only necessary for storing anonymous types. In all other cases they are just a convenience. If the value of the variable never changes, just give it an explicit type. Attempting to use the readonly modifier with an implicitly typed local will generate CS0106.

    To correct this error

    If you require the variable to be constant or readonly, give it an explicit type.

    0 讨论(0)
提交回复
热议问题