1

I am trying to get my head around some of my predecessors code who, helpfully, has used 'var' to declare everything.

I have a using statement which is below:

using (var postStream = request.GetRequestStream())
{
    postStream.Write(byteData, 0, byteData.Length);
}

When I put a breakpoint here, postStream shows up in the Autos window as System.Net.ConnectStream. Instead of 'var' I want to use 'ConnectStream' but the compiler doesn't like this.

What am I missing, why can't I write my code like this:

using (ConnectStream postStream = request.GetRequestStream())
{
    postStream.Write(byteData, 0, byteData.Length);
}

I know this is trivial but I was always taught not to use 'var' unless you have a specific reason to do so (such as when dealing with LINQ). Am I wrong?

johnnyRose
  • 7,310
  • 17
  • 40
  • 61
JMK
  • 27,273
  • 52
  • 163
  • 280
  • 1
    var is your friend :) and also you don't have to put breakpoint there to know the type. Just hover over var and it will tell the type. – Beku Jan 19 '12 at 16:53
  • @Beku, it will tell the declared type, not the actual type of the instance; ConnectStream is not a public class, so in this case it will only show as Stream (the declared returned type of GetRequestStream) – Thomas Levesque Jan 19 '12 at 16:56
  • @ThomasLevesque But stream is enough to remove the var, which was causing trouble to the reader of the code. – Beku Jan 19 '12 at 16:58
  • Thankyou both, you learn something new every day! – JMK Jan 19 '12 at 17:06
  • 1
    In Visual Studio you can see what type "var" is inferred to be by mousing over it. As long as you do that it's the same as typing it out, unless you intentionally assign to a supertype reference. – Hans Apr 22 '14 at 19:45
  • @Hans Thanks, although I asked this over 2 years ago when I was still getting to grips with C#, how time flies! – JMK Apr 22 '14 at 20:58
  • Sorry to dredge it up, so's a living resource so I thought I'd leave this for others who find it in search. – Hans Apr 22 '14 at 22:52
  • @Hans No worries, some times it's nice to be reminded of things you used to struggle with which now seem second nature :) – JMK Apr 23 '14 at 23:22

3 Answers3

10

ConnectStream is an internal class, you can't use it explicitly. But it doesn't matter, because you don't need to know that its actual type is ConnectStream: all you need to know is that it's a Stream (the return type declared by GetRequestStream), the actual implementation doesn't really matter.

If you want to specify the type explicitly, just write it like this:

using (Stream postStream = request.GetRequestStream())
{
    postStream.Write(byteData, 0, byteData.Length);
}

(but it has exactly the same meaning as using var)

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • 6
    +1 "because you don't need to know that it's actual type is" - "all you need to know is that it's a stream." – Bobby Cannon Jan 20 '12 at 13:13
  • 1
    @BobbyCannon I *wish* **wish** this were true. Unfortunately the System.Net.ConnectStream violates the Liskov Substitution Principle, so you can't treat it like a standard stream. – Jimmy Hoffa Aug 26 '13 at 20:23
  • @JimmyHoffa, how does it violate the LSP? – Thomas Levesque Aug 26 '13 at 20:56
  • @ThomasLevesque As with a variety of the Stream implementations, it throws NotImplementedException when you try to access the Length property, and one or two other properties. The whole family of the inheritance hierarchy for Stream are often guilty of these types of Liskov violations. Annoying. – Jimmy Hoffa Aug 26 '13 at 21:10
  • 3
    @JimmyHoffa, there is a CanSeek property that must be true to access the Length property, otherwise it throws NotSupportedException. This exception is documented in the [Stream.Length documentation](http://msdn.microsoft.com/en-us/library/system.io.stream.length.aspx). ConnectStream does respect this contract, so I don't think it violates the LSP. – Thomas Levesque Aug 27 '13 at 00:51
  • Not sure about LSP, but I do feel it violates "Interface segregation principle" ("'i" in SOLID). Feels a lot like you've got a Write interface, a Read interface and a Seek interface all jammed into one class. – Drew Delano Jan 07 '16 at 23:24
2

Theres a great snippet from the var keyword on the InfoQ site. This talks about when and when not to use var. Its not quite as clear cut as don't' use it unless your using linq, its more you use it when you don't need to draw attention to the data type and use typed objects when you need to draw attention to the data type.

Its one of the personal preference things... but normally the best preference is however your boss/code lead/architect likes their code 'grammar' to look to make it uniform.

John Mitchell
  • 9,653
  • 9
  • 57
  • 91
0

I reused one answer from here: How do I get the filesize from the Microsoft.SharePoint.Client.File object?

It' reply from 'Freejete' and his method 'ReadToEnd' worked like a charm for me.

Community
  • 1
  • 1
Diomos
  • 420
  • 5
  • 15