2011-05-16 87 views
9

我有一个在C#中反对类型推断的同事。我相信他的大部分论点都缺乏可读性。我反对的观点是,Visual Studio的智能感知功能提供了一种查看类型的简单方法,并且从代码中读取它们不像编写出记事本时那样必要。C#中的类型推断有哪些优点和缺点?

但是,我很好奇在C#中使用类型推断的优缺点。我来自C++,并且我知道C++ 0x的'auto'有更客观的好处,因为你并不总是知道你得到的类型(特别是在进行繁重的模板编程时)。一个例子是使用auto来存储Boost.Bind的值。

在C#中,类型推断似乎没有太多的要求,因为它是一个“很好有”或糖衣功能。我认为这将是当你正在处理long类型有用的,例如:

Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>> myVar = obj.GetLazy(); 

这将是:

var myVar = obj.GetLazy(); 

这是在我看来,更清洁。但是,有没有客观的论据来反驳类型推断?使用它是否是一种很好的编程习惯,即使在可争论的情况下它不提供任何好处(例如,使用'var'而不是'int')?

一些帮助理解我应该如何在日常编码中使用'var'会很好。

+1

ReSharper似乎告诉我使用'var'很多... – NickAldwin 2011-05-16 15:55:56

+6

请参阅http://blogs.msdn.com/b/ericlippert/archive/2011/04/20/uses-and-misuses-of- implicit-typing.aspx – 2011-05-16 15:57:44

+0

好吧,如果你问我,明确指定类型应该是一个非常罕见的例外,即使这样你也应该使用你可能使用的最常用的类型。但是再次,我主要使用Python编程(duck typing),并且非常喜欢Haskell(类型推断)和结构化类型。 – delnan 2011-05-16 16:03:35

回答

8

类型推断的发明源于您为C++所提供的原因,您可以创建不具有类型名称的匿名类型(特别参见Lambdas和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(); 

但可能会因人而异。

2
var myVar = obj.GetLazy(); 

这种类型的推理,在intellisense的存在下,是一个大致的好主意,或者说是好的。但是,如果没有智能感知,那么我不认为这是一个好主意。相反,这将是一场噩梦。如果没有智能感知,我相信大多数开发人员会不喜欢它,因为缺乏智能感知(以及确切类型)所带来的不便。

不过,即使没有智能感知,下面将是一件好事:

var obj = new Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>(); 

在这种情况下,类型推断是解脱,因为它避免了大量的打字和复制打字!

带或不带智能感知,我喜欢写:

Lazy<List<MyNamespace.ISomeVeryLongInterfaceType> obj= obj.GetLazy(); 
+1

即使有intellisense,也不清楚在这里检索的是哪种类型,当然,如果有人能够浏览代码并知道发生了什么,如果在这种方法中有10行代码需要经过并且将鼠标悬停在每个对象上/为每条线路启动intellisense,发生这种情况 - 如果必须这样做,我会生气 – jcvandan 2011-05-16 16:02:24

4

隐式类型可以在别人在某些情况下是有用的,有害的。 Eric Lippert最近在Uses and misuses of implicit typing上发表了一篇值得一读的文章。

有一点需要记住,var仅供用户使用,编译时编译器会将其转换为具体的表示形式。

其中一个缺点是使用类的接口。

假定GetCurrentList()返回IList<string>

IEnumerable<string> list = GetCurrentList(); 

var list = GetCurrentList(); 

是不一样的,在第二个例子中,列表将是一个IList<string>

我倾向于使用明确的类型,通常只使用var,因为它有助于代码的可读性和使用匿名类型(因为您必须在那一点上)。

4

我认为常理以下非正式规则:

如果有一些长的名字,如:

Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>> myVar = new Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>>(); 

然后用

var myVar = new Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>>(); 

更换这是有道理的,因为你仍然可以告诉对象是什么。

东西模糊的,而另一方面,可能保证不使用var

Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>> myVar = doProcess(); 
2

我喜欢用类型推断使代码更简洁,不过我只使用它时,我可以看到它是什么类型在同一行,例如:

var myClass = new MyClass(); 

MyClass myClass = RandomFuncThatGetsObject(); 

我认为在第一个示例中使用var不会影响可读性,事实上它使得它更具可读性,但是在第二个示例中使用var会影响可读性。

var x = new { Greeting = "Hello", Name = "World" }; 

当您使用LINQ查询时,您通常使用匿名类型的所有时间:当您正在使用匿名类型

2

类型推断是必要的。

相关问题