C# 中类型推断的优点和缺点是什么?
What are some advantages & disadvantages of type inference in C#?
我有一个反对C#类型推断的同事。我相信他的大部分论点都围绕着缺乏可读性。我反对这一点的论点是,Visual Studio 的智能感知功能提供了一种查看类型的简单方法,并且从代码中读取它们并不像我们在记事本中编码那样必要。
但是,我对在 C# 中使用类型推断的优缺点感到好奇。我来自C++,我知道C++0x的"auto"有一个更客观的好处,因为你并不总是知道你得到的类型(特别是在进行繁重的模板编程时)。例如,使用 auto 来存储 Boost.Bind 的值。
在 C# 中,类型推断似乎并不那么重要,因为它是一个"很高兴拥有"或糖衣功能。我认为当您处理长类型时,它会很有用,例如:
Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>> myVar = obj.GetLazy();
它将是:
var myVar = obj.GetLazy();
在我看来,这要干净得多。但是,是否有任何客观的论据支持OR反对类型推断?使用它是否是一种良好的编程实践,即使在有争议的情况下它没有提供任何好处(例如,使用"var"而不是"int")?
在理解我应该如何在日常编码中使用"var"方面有一些帮助会很棒。
类型推断的发明正是出于您给出C++的原因,您可以创建没有类型名称的匿名类型(特别是参见 Lambda 和 Linq)。
所以在这种情况下,它是需要的。
在另一种情况下(当类型名称已知时),则归结为样式。当类型非常明显时,我使用var
:
// I like this - less duplication and easier to read
var item = new List<ComplexObjectItem>();
而不是:
List<ComplexObjectItem> item = new List<ComplexObjectItem>();
因为它减少了重复。
但是,当类型对读者来说不是很明显时,我宁愿不使用它:
// I don't like this - I need to look up what the type is
var item = ResultOfSomeFunctionWhereICantSeeWhatItIs();
但您的里程可能会有所不同。
我认为常识决定了以下非正式规则:
如果有一些长名称,例如:
Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>> myVar = new Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>>();
然后将其替换为
var myVar = new Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>>();
这是有道理的,因为你仍然可以分辨出对象是什么。
另一方面,模棱两可的东西可能需要不使用var
:
Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>> myVar = doProcess();
隐式类型在某些情况下可能有用,但在其他情况下有害。Eric Lippert最近发表了一篇关于隐式类型的使用和误用的文章,值得一读。
要记住的一件事是,var
仅适用于用户,编译器在编译时会将其转换为其具体表示形式。
一个缺点是使用类中的接口时。
假设GetCurrentList()
返回一个IList<string>
:
IEnumerable<string> list = GetCurrentList();
和
var list = GetCurrentList();
与第二个示例中不同,列表将是一个IList<string>
。
我倾向于使用引出类型,通常只在有助于代码的可读性和匿名类型时使用var
(因为此时您必须这样做)。
使用类型推断来使代码更简洁,但是我只在可以看到它在同一行上的类型时才使用它,例如:
var myClass = new MyClass();
但
MyClass myClass = RandomFuncThatGetsObject();
我认为在第一个示例中使用 var 不会影响可读性,实际上它使其更具可读性,但是在第二个示例中使用 var 会影响可读性。
使用匿名类型时,类型推断是必需的:
var x = new { Greeting = "Hello", Name = "World" };
使用 LINQ 查询时,通常始终使用匿名类型。
var myVar = obj.GetLazy();
在智能感知的存在下,这种类型推断是一个大致的好主意,或者说没问题。但是,如果没有智能感,那么我不会认为这是一个好主意。这将是一场噩梦。如果没有智能感知,我相信大多数开发人员会不喜欢它,因为缺乏智能感知(和确切类型,两者兼而有之)会带来不便。
但是,即使没有智能感知,以下内容也会很好:
var obj = new Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>();
在这种情况下,类型推断是一种解脱,因为它避免了大量的键入和重复键入!
无论有没有智能感知,我更喜欢写:
Lazy<List<MyNamespace.ISomeVeryLongInterfaceType> obj= obj.GetLazy();
- 使用rdtsc进行基准测试的缺点是什么
- 将字段(在类中)定义为引用的缺点是什么?
- 嵌套向量的缺点是什么?
- 模板而不是接口的缺点是什么?(C++)
- 在C 项目中剩下未使用的类的缺点是什么?
- 在64位系统上创建一个非常大的数组的缺点是什么
- C++协方差返回类型的缺点是什么
- 在将GITHUB库包含在您的项目中之前,汇编GitHub库的优点 /缺点是什么?
- 单源项目结构的缺点是什么?
- 仅使用UDP托管小型服务器应用程序的缺点是什么
- 抛弃灾难的例外 - 缺点是什么
- 使用继承来减少重复代码的缺点是什么
- 以不同方式实现可变参数构造函数的模板类:每个版本的优点和缺点是什么
- 如果使单一实例构造函数受到保护,缺点是什么 - 继承 - C++11.
- 为C++提供标准GUI库的缺点是什么
- 如何访问类变量?公共方法/getters与继承.优点和缺点是什么
- 对所有异常使用一个基类的缺点是什么?
- 使用AVL树的缺点是什么?
- "upcasting"的缺点是什么?
- OpenGL函数在命名空间gl中的缺点是什么?