The Difference Between vbCrLf, vbNewLine and Environment.NewLine

The question, "which is better, vbCrLf, ContrlChars.CrLf, vbNewLine, ControlChars.NewLine, Environment.NewLine, ControlChars.NewLine, or vbNewLine?" is not a question you'd get in C#, since only Environment.NewLine is available.  This is a question that only appears during VB.NET development.

So what's the difference between the following five statements?

Debug.Print(vbCrLf)
Debug.Print(ControlChars.CrLf)
Debug.Print(vbNewLine)
Debug.Print(ControlChars.NewLine)
Debug.Print(Environment.NewLine)

Usually, nothing.  They all return a carriage return followed by a line feed ("\r\n").  The last one, Environment.NewLine, is a little special and there is one case where it may return something different.

vbCrLf

vbCrLf is a carry-over from old-school VB days and, for the sake of veteran VB developers, was retained.  It actually is a constant declared in the Microsoft.VisualBasic.Constants class, so it can be referred to as Constants.vbCrLf too.  I wouldn't be surprised if this constant were eventually dropped in future versions of the VB.NET language.  There's also another constant with the same value defined as ControlChars.CrLf.  All will return the value "\r\n", indicating a carriage return (vbCr or "\r") followed by a line feed (vbLf or "\n").  In Windows, typically both are expected, even though sometimes you'll find folks using either one or the other and it is usually rendered correctly.  However, I don't recommend the practice of using one or the other, or even the string "\r\n".  Better to just let a predefined constant (like any one of the five mentioned in this article) to do the job.  But like I said earlier, I suspect this constant is on its way out and will likely become deprecated and obsolete.

vbNewLine

vbNewLine (or Constants.vbNewLine) is identical to vbCrLf, just a little easier to understand for newer developers.  It can also be referred to as ControlChars.NewLine.  These constants also return the value "\r\n".

Downside of ControlChars.CrLf and ControlChars.NewLine

So it's established that vbCrLf and vbNewLine are identical to ControlChars.CrLf and ControlChars.NewLine, respectively.  So although we've got four constants that all really mean the same thing (which is typically ill-advised, since any redundant code or constants are more costly to change later), the main drawback is that they are all VB.NET specific.  Unless you import the Microsoft.VisualBasic reference to your C#, C++, or F# project, none of these constants are available in your code when working with non-VB.NET projects.  These are all constants written solely for the convenience of the Visual Basic.NET developer.

Environment.NewLine

Environment.NewLine in my opinion is the most versatile and the one I recommend.  Not only is it the only one of these five options also available in C#, making it the most universal, but it has the added benefit of being platform-independent.  Well, at least it's intended to work in either Windows or Unix environments.  In the case of Unix, there is no need for a carriage return, just a new line ("\n") character will suffice.  So for compatibility between both platforms, this property (emphasizing here that it's a property and not a constant) will adjust and return either "\r\n" in Windows or simply "\n" in Unix.

The one downside is that it can't be used to define a constant; it's a read-only property, not a constant itself like the other options.

Const x As String = "Testing as a constant" & Environment.NewLine ' Doesn't compile

The above will throw the error "Constant expression is required" at design / compile time.  In this particular case, I'd recommend using ControlChars.NewLine instead.

ControlChars Class in C#

Here's the source for the ControlChars class written in C#, for the case where you don't want to or can't use Environment.NewLine:

  public sealed class ControlChars
  {
    public const string CrLf = "\r\n";
    public const string NewLine = "\r\n";
    public const char Cr = '\r';
    public const char Lf = '\n';
    public const char Back = '\b';
    public const char FormFeed = '\f';
    public const char Tab = '\t';
    public const char VerticalTab = '\v';
    public const char NullChar = '\0';
    public const char Quote = '"';
  }

So to sum it up, all five options return the exact same value, except for Environment.NewLine, which can adapt to the platform on which your application is running.  If you don't believe your application will ever run on another platform but Windows (but why limit yourself?) and you anticipate no possibility of ever using C#, then I would recommend at least being consistent and ensure your entire solution uses only one of these constants.

Optional Parameters in C# 4.0

As a C# developer who has done a fair amount of coding in VB.NET too, I've wanted to use optional parameters for some of my overloaded methods long before the capability existed.  Fortunately, optional parameters finally do exist in C# .NET 4.0.

Prior to .NET 4, something like the following needed to be done to effectively allow optional parameters by essentially overloading the same method name multiple times, with a different number of parameters in each signature:

class OptionalParametersTest
{
	public void SomeMethod(string a)
	{
		SomeMethod(a, "default value", "default value");
	}

	public void SomeMethod(string a, string b)
	{
		SomeMethod(a, b, "default value");
	}

	public void SomeMethod(string a, string b, string c)
	{
		Console.WriteLine(string.Format("a: {0}, b: {1}, c: {2}", a, b, c));
		// Additional code here
	}
}

Here's a sample invoking each of these three overloaded methods:

var optionalParametersTest = new OptionalParametersTest();

optionalParametersTest.SomeMethod("1");
optionalParametersTest.SomeMethod("1", "2");
optionalParametersTest.SomeMethod("1", "2", "3");

This will output:

a: 1, b: default value, c: default value
a: 1, b: 2, c: default value
a: 1, b: 2, c: 3

Here's the same class in the first listing, OptionalParametersTest, but rewritten using optional parameters:

class OptionalParametersTest
{
	public void SomeMethod(string a, string b = "default value", string c = "default value")
	{
		Console.WriteLine(string.Format("a: {0}, b: {1}, c: {2}", a, b, c));
		// Additional code here
	}
}

The output is exactly the same:

a: 1, b: default value, c: default value
a: 1, b: 2, c: default value
a: 1, b: 2, c: 3

The notation, adding " = default value" after the name of the parameter, is familiar to VB.NET developers too.  And, just like in VB.NET, optional parameters must be defined last; you can't make the first parameter optional if the next one isn't.

But what if you want the second parameter (optional) to remain optional but define the third (also optional) parameter?  How can you get the following result?

a: 1, b: default value, c: 3

The trick is to omit the second parameter and define the third with a colon:

optionalParametersTest.SomeMethod("1", c : "3");

In the above line, we didn't bother specifying the parameter named "b" and instead just indicated that we wanted to define parameter "c".  This instructed the method to use the default value of "b" while still allowing the "c" parameter to be passed in.

Man, there are so many times I wished I could have done this before C# 4.0 hit the scene.