我有一个同事反对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'会有所帮助。
答案 0 :(得分: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();
但你的里程可能会有所不同。
答案 1 :(得分:4)
隐式输入在某些情况下可能有用,而在其他情况下则有害。 Eric Lippert最近发表了一篇关于Uses and misuses of implicit typing的文章,值得一读。
有一点需要记住,var
仅适用于用户,编译器在编译时将其转换为具体表示。
一个缺点是使用类中的接口。
假设GetCurrentList()
返回IList<string>
:
IEnumerable<string> list = GetCurrentList();
和
var list = GetCurrentList();
与第二个示例中的不同,列表将是IList<string>
。
我倾向于使用外显输入,并且通常只使用var
,因为它有助于代码的可读性和使用匿名类型时(因为你必须在那时)。
答案 2 :(得分: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();
答案 3 :(得分:2)
var myVar = obj.GetLazy();
这种类型的推理,在智能感知的存在下,是一个大致好的想法,或者没问题。但是,如果没有智能感知,那么我认为这不是一个好主意。这将是一场噩梦。没有intellisense,我相信大多数开发人员会不喜欢它,因为缺乏intellisense(和确切类型,两者)造成的不便。
然而,即使没有智能感知,以下情况也会很好:
var obj = new Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>();
在这种情况下,类型推断是一种解脱,因为它避免了大量的输入和重复输入!
有或没有intellisense,我更喜欢写:
Lazy<List<MyNamespace.ISomeVeryLongInterfaceType> obj= obj.GetLazy();
答案 4 :(得分:2)
我喜欢使用类型推断来使代码更简洁,但是当我能看到它在同一行上的类型时我只使用它,例如:
var myClass = new MyClass();
BUT
MyClass myClass = RandomFuncThatGetsObject();
我认为在第一个例子中使用var不会影响可读性,实际上它使它更具可读性,但是在第二个例子中使用var会影响可读性。
答案 5 :(得分:2)
使用匿名类型时,类型推断是必要的:
var x = new { Greeting = "Hello", Name = "World" };
使用LINQ查询时,通常一直使用匿名类型。