有什么优点和优点; C#中类型推断的缺点?

时间:2011-05-16 15:51:27

标签: c# c++ visual-studio intellisense type-inference

我有一个同事反对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'会有所帮助。

6 个答案:

答案 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查询时,通常一直使用匿名类型。