Compartilhar via


What Are The Semantics Of Multiple Implicitly Typed Declarations? Part One

In my earlier series on inferring a unique "best" type from a set of expressions I mentioned that one potential application of such an algorithm is in implicitly typed variables. This led to some good questions and concerns posted in the comments - questions and concerns which echo similar feedback we've been receiving from a variety of sources since we released the first technology preview of C# 3.0 last year.

I'd like to run a quick unscientific poll to see what your intuitions and expectations about implicitly typed variables with multiple declarations are. Please leave a comment describing what you think should happen here, and why you think that.

1: local variable declaration var x = 1, y = 2.0; has the same semantics as:
(a) double x = 1, y = 2.0;
(b) int x = 1; double y = 2.0;
(c) object x = 1, y = 2.0;
(d) this should be a compile-time error
(e) something else, please specify

2: local variable declaration var q = 0, r = (short)6; has the same semantics as:
(a) int q = 0; short r = 6;
(b) int q = 0, r = 6;
(c) short q = 0, r = 6;
(d) object q = 0, r = 6;
(e) this should be a compile-time error
(f) something else, please specify

Thanks! Next time I'll describe some of the pros and cons of each and what our current thinking is in this area.

Comments

  • Anonymous
    June 26, 2006
    Definitely 1b, 2a. The general rule I'm going with here is that

    var a=A, b=B;

    should be exactly equivalent to:

    var a=A;
    var b=B;

    In a sense this is exactly equivalent to the way that other multiple declarations work - if you replace "var" with any real type, this equivalence holds. So I think it passes the "intuitive" test a lot better than any of the other options.
  • Anonymous
    June 26, 2006
    I'd agree with 1b, 2a also. Though I come to that from interpreting what the coder was thinking of when declaring variables. If lacking type information then I'd presume that things are typed into the most restrictive logical data type given information about the initialisation value. Thus leaving the programmer to explicitly define alternative types, as per the syntax of question 2. I'd also agree that var a=B, b=B is equivalent to var a=A; var b=B.
  • Anonymous
    June 26, 2006
    1e, 2e

    Ambiguity, as I've found, is the primary cause of subtle bugs in code. Given that it should be illegal to put yourself in to a position like that. Or, it should be a compile-time warning, though given that you can't get rid of the warning unless you change the type, it might as well be an error.

    "In a sense this is exactly equivalent to the way that other multiple declarations work - if you replace "var" with any real type, this equivalence holds. So I think it passes the "intuitive" test a lot better than any of the other options."

    Except under that logic you could put:

    int a = 2, b = "hello";

    I think intuitive tests have to pass both directions here. Since I can't translate:

    int a = 2;
    string b = "hello";

    into

    int a = 2, b = "hello";
    or
    string a = 2, b = "hello";

    I shouldn't, intuitively, be able to translate the var equivalents. Hence, it fails the bidirectional argument.
  • Anonymous
    June 26, 2006
    The comment has been removed
  • Anonymous
    June 26, 2006
    The comment has been removed
  • Anonymous
    June 26, 2006
    My answers (without looking at any other comments) would be:

    1 (b)
    2 (a)

    I think there should be no difference between:

    var x = 1, y = 2.0;

    and

    var x = 1;
    var y = 2.0;

    And similarly, no difference between:

    var q = 0, r = (short) 6;

    and

    var q = 0;
    var r = (short) 6;

    Applying the type inference rules: 0 -> int, 1 -> int, 2.0 -> double, (short) 6 -> short leads to my given answers. That said, I could definitely live with flagging both as compilers errors, so answer (d).
  • Anonymous
    June 26, 2006
    1 = b and 2 = a, if only because this is what I'm used to from every other language I know of that uses type inference.
  • Anonymous
    June 26, 2006
    The comment has been removed
  • Anonymous
    June 26, 2006
    1b 2a

    Yeah it's a bit annoying at first glance, but I think it works the best.
  • Anonymous
    June 26, 2006
    1a, 2b: We should be able to do x = y and y = x. A valid reason to use  multiple declarations (the only readon I can think of) is to be sure that we end up with two locals with the same type.
  • Anonymous
    June 26, 2006
    The comment has been removed
  • Anonymous
    June 26, 2006
  1. b
    2) a
  • Anonymous
    June 26, 2006
    1a, 2b

    I think it would be tedious to debug code where expressions are used to initialise the variables if multiple type can be initialised implicitly in a single statement.  In the interest of mainatiablility, I feel this should be flaged as an error / warning, or the largest data type would be used.  Having said that, it would be a problem if var x = 1, y = 2.0, z="abc"; has to be parsed and hence my answer applies if we are dealing with similar data type.
  • Anonymous
    June 26, 2006
    The comment has been removed
  • Anonymous
    June 26, 2006
    1b
    2a
    I think a good reason to avoid options 1a, 2b and 2c is that if the author wants the same type they need only write it instead of var. Therefore treating it the same as multiple var declarations makes more sense to me.
  • Anonymous
    June 26, 2006
    The comment has been removed
  • Anonymous
    June 26, 2006
    The comment has been removed
  • Anonymous
    June 26, 2006
    My first intuition is also 1b, 2a.  

    But since not everybody agrees about what is intuitively correct, I would actually recommend 1d, 2e.  Like some have said before, it's just a bug waiting to happen.
  • Anonymous
    June 27, 2006
    The comment has been removed
  • Anonymous
    June 27, 2006
    That's interesting.  In VB6 if you say

    Dim Curly, Larry, Moe as Stooge

    of course that means that Curly and Larry are Variant, Moe is a Stooge.  

    My guess would be that your VB6 veterans are familiar with the pain that this "gotcha" causes and would like C# to not add a similar gotcha to the language.  

    (.NET versions of VB will treat all three as Stooges.)


  • Anonymous
    July 05, 2006
    Of course
    1(b)
    2(a)

    If you give only a number to the compiler, e.g. 2.0, the compiler will recognize the const as a double. Except you explictly specify 2.0f to make it a float. The type is clear even though it is under C# 1.0 specification.

    And I think the "var" keyword should better be used with anonymous class. You cannot specify any other class type to the variables except itself and object. We certainlly don't want the compiler to cast it to an object. Of course we also don't want compiler to change 0(int) into float, double or object.