代码之家  ›  专栏  ›  技术社区  ›  balexandre

使用什么:var或对象名类型?[复制品]

  •  52
  • balexandre  · 技术社区  · 17 年前

    这个问题已经有了答案:

    这是一个在编程时我总是想知道的问题:当我们编写代码时应该使用什么:

    var myFiles = Directory.GetFiles(fullPath);
    

    string[] myFiles = Directory.GetFiles(fullPath);
    

    var 是新的,是一个 隐式类型 ,所以我们只能在本地使用,它有不能为空等规则,但我想知道我们是否能“正常”使用它。

    “正常”部分说,而不是 匿名类型 , 对象和集合初始化器 查询表达式 这就是使用var匿名对象的意图,所以我的意思是…就像上面的例子。

    你有什么想法?

    8 回复  |  直到 8 年前
        1
  •  61
  •   Robert Rossney    17 年前

    除了显而易见的用途 var 对于Linq,我还使用它来缩写毛茸茸的变量声明以提高可读性,例如:

    var d = new Dictionary<string, Dictionary<string, Queue<SomeClass>>>();
    

    总的来说,静态输入让我不愿意放弃它,这给了我一种安慰(因为我想要一个更好的单词)。我喜欢这样的感觉,当我声明一个变量时,我知道我在做什么。声明变量不仅仅是告诉编译器一些事情,它还告诉读取代码的人一些事情。

    让我举个例子。假设我有一个方法返回 List<string> . 这段代码当然是正确的,我认为90%的C开发人员可能会这样写:

    List<string> list = MyMethod();
    

    很明显,对吧?事实上,这是一个你可以很容易使用的地方 var .

    真的。但是 代码的版本不仅仅是声明一个变量,它还告诉我编写代码的人打算做什么:

    IEnumerable<string> list = MyMethod();
    

    编写代码的开发人员告诉我“我不会更改这个列表,也不会使用索引来访问它的成员。我要做的就是迭代它,“这是在一行代码中需要了解的大量信息。如果你使用它,你就会放弃 var .

    当然,如果你一开始不使用它,你就不会放弃它。如果你是那种会写那行代码的开发人员,你已经知道你不会使用 var 那里。

    编辑:

    我刚刚重读了乔恩·斯基特的文章,埃里克·利珀特的这句话突然出现在我面前:

    隐式类型化局部变量只是一种很小的方法,在这种方法中可以淡化“如何”并强调“什么”。

    我认为,实际上在很多情况下,使用隐式类型会留下隐式的内容。不谈什么也没关系。例如,我将随意编写一个Linq查询,如下所示:

    var rows = from DataRow r in parentRow.GetChildRows(myRelation)
               where r.Field<bool>("Flag")
               orderby r.Field<int>("SortKey")
               select r;
    

    当我读到这段代码时,我想当我读到它的时候 rows 是一个 IEnumerable<DataRow> “因为我知道Linq查询返回的是 IEnumerable<T> 我可以看到被选中对象的类型。

    这是一个例子 还没有 已明确表示。它留给我去推断。

    现在,在我使用LINQ的大约90%的情况下,这一点都不重要。因为90%的时间,下一行代码是:

    foreach (DataRow r in rows)
    

    但不难想象在代码中声明 作为 IEnumerable<数据行> -代码中查询了许多不同类型的对象,将查询声明放在迭代旁边是不可行的,并且能够检查 智能感知。这是什么东西,而不是怎样的东西。

        2
  •  41
  •   Jon Skeet    17 年前

    对于这个问题,你会有很多不同的看法——从“随处使用var”到“只使用匿名类型的var,基本上你必须这样做。”我喜欢 Eric Lippert's take on it :

    所有代码都是抽象的。是什么 代码是_真的_做的是 操纵数据?号码?位? 不,电压?不是电子吗?是的,但是 在以下级别理解代码 电子是个坏主意!艺术 编码就是找出正确的方法 抽象层次是为了 观众。

    在高级语言中 总是这种紧张关系 代码执行(语义上)以及 代码完成它。维护 程序员需要理解这两者 如果他们要去的话怎么办? 成功地做出改变。

    Linq的重点是 大量地去强调“如何”和 大量强调“什么”。通过 使用查询理解, 程序员对未来说 观众“我相信你应该 既不知道也不关心这到底是怎么回事 正在计算结果集,但您 应该非常关心 结果集的语义是。” 它们使代码更接近 正在实施的业务流程和 远离比特和电子 就这样走了。

    隐式类型的局部变量只是一个 小方法,你可以去强调 如何并因此强调 什么。这是否正确 在特定情况下,要做的是 判断调用。所以我告诉人们 如果相关类型的知识 它的选择对 方法的持续操作, 然后不要使用隐式类型。 明确的打字说“我告诉你 为什么会这样,付钱 “注意”。隐式输入表示“it 这一点无关紧要 事情是一个清单还是一个 客户[],重要的是 客户的集合。”

    就我个人而言,我没有 倾向 如果类型不太明显,就使用它——在这里,我将LINQ查询包含为“相当明显”。我不会这么做的 Directory.GetFiles 例如,由于不太明显,它返回 string[] 而不是 FileInfo[] (或者完全是其他的事情)-这对你以后的工作有很大的影响。

    如果在赋值运算符的右侧有一个构造函数调用,那么我更可能使用 var :这是显而易见的类型。这对于复杂的泛型类型尤其方便,例如 Dictionary<string,List<int>> .

        3
  •  11
  •   Lasse V. Karlsen    17 年前

    我个人只在两个地方使用VaR:

    1. 对于匿名类型,例如与LINQ相关(在某些情况下需要var)
    2. 当语句声明并构造同一类型的特定类型时

    即,这是第2点的一个例子:

    var names = new List<String>();
    

    编辑 这是对乔恩·斯基特问题的回应。

    上述答案实际上是简化的。基本上,我用 var 其中类型为:

    1. 不需要知道(虽然不是很多地方)
    2. 不可能知道(LINQ,匿名类型)
    3. 或者从代码中清除

    在工厂方法的情况下,在编写代码的地方,您所需要知道的是,返回的对象是某种类型的后代,并且 某种类型 有一个静态工厂方法,那么我将使用 var . 这样地:

    var connection = DatabaseConnection.CreateFromConnectionString("...");
    

    上面的示例是我的代码中的一个真实示例。很明显,至少对我和使用此代码的人来说, 连接 是一个databaseconnection子代,但不需要确切的类型来理解或使用代码。

        4
  •  9
  •   Inisheer    17 年前

    我尝试了“到处使用var”的风格…这就是为什么我没有继续使用它。

    1. 有时可读性降低
    2. 在之后限制IntelliSense=
    3. 键入“var”实际上并不比键入“int”、“string”等短得多,尤其是在intellisense中。

    尽管如此,我还是在Linq中使用它。

        5
  •  3
  •   yfeldblum    16 年前

    来自函数编程的领域,在那里类型推理统治着一天,我使用 var 尽可能为所有当地人。

    在Visual Studio中,如果您想知道本地语言的类型,只需将鼠标悬停在它上面。

        6
  •  3
  •   Andres Denkberg    17 年前

    这个 post 在何时使用var类型接口或对象类型上有一些好的指导线。

        7
  •  3
  •   AleÅ¡ Roubíček edbond    16 年前

    我倾向于使用 var 但我的同事说,不管在哪里,它对我们来说都是不可读的。所以现在我用 var 仅限于匿名类型、LINQ查询以及右侧的where is构造函数。

        8
  •  1
  •   mithrandi    17 年前

    我想这是有趣的注意到这通常是如何处理哈斯克尔。多亏了 Curry-Howard isomorphism 可以推断haskell中任何表达式的(最一般的)类型,因此在任何地方基本上都不需要类型声明,但有一些例外;例如,有时您故意希望将类型限制为比推断的更具体的类型。

    当然,所需要的和推荐的不是同一件事;实际上,约定似乎是顶级定义总是有类型声明,而本地化定义则忽略了类型声明。这似乎在定义整体可读性的明确性与本地“助手”或“临时”定义的可读性的简洁性之间取得了良好的平衡。如果我理解正确,你就不能用 var 对于“顶级”定义(如方法或全局函数),首先,我猜这意味着“使用 var 在C世界里,你可以去任何地方。当然,打字” int “击键次数是否与” var “,但大多数例子会比这长。

    推荐文章