How to use C# 6 with Web Site project type?
I've tested this with ASP.NET MVC 5 (tested 5.2.3), and your mileage may vary with other web frameworks, but you just need to add the NuGet package for Roslyn CodeDOM.
Microsoft.CodeDom.Providers.DotNetCompilerPlatform
should add the DLL files...
PM> Install-Package Microsoft.CodeDom.Providers.DotNetCompilerPlatform
Replacement CodeDOM providers that use the new .NET Compiler Platform ("Roslyn") compiler as a service APIs. This provides support for new language features in systems using CodeDOM (e.g. ASP.NET runtime compilation) as well as improving the compilation performance of these systems.
...and also add the following to your web.config:
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" />
</compilers>
</system.codedom>
If the XML is still missing, try adding yourself.
C# 6.0 Features Not Working with Visual Studio 2015
This works in MVC 5 (tested 5.2.3), you just need to add the roslyn code dom Nuget package
CodeDOM Providers for .NET Compiler...
Replacement CodeDOM providers that use the new .NET Compiler Platform ("Roslyn") compiler as a service APIs. This provides support for new language features in systems using CodeDOM (e.g. ASP.NET runtime compilation) as well as improving the compilation performance of these systems.
PM> Install-Package Microsoft.CodeDom.Providers.DotNetCompilerPlatform
https://www.nuget.org/packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/
Detect c# 6 features with Roslyn
You can use this Walker for detecting C# 6 syntax features:
public class CSharp6FeaturesWalker : CSharpSyntaxWalker
{
public bool CSharp6Features { get; private set; }
public CSharp6FeatureWalker()
{
}
public override void VisitPropertyDeclaration(PropertyDeclarationSyntax node)
{
if (node.ExpressionBody != null)
{
CSharp6Features = true;
}
else if (node.Initializer != null)
{
CSharp6Features = true;
}
base.VisitPropertyDeclaration(node);
}
public override void VisitMethodDeclaration(MethodDeclarationSyntax node)
{
if (node.ExpressionBody != null)
{
CSharp6Features = true;
}
base.VisitMethodDeclaration(node);
}
public override void VisitOperatorDeclaration(OperatorDeclarationSyntax node)
{
if (node.ExpressionBody != null)
{
CSharp6Features = true;
}
base.VisitOperatorDeclaration(node);
}
public override void VisitConversionOperatorDeclaration(ConversionOperatorDeclarationSyntax node)
{
if (node.ExpressionBody != null)
{
CSharp6Features = true;
}
base.VisitConversionOperatorDeclaration(node);
}
public override void VisitIndexerDeclaration(IndexerDeclarationSyntax node)
{
if (node.ExpressionBody != null)
{
CSharp6Features = true;
}
base.VisitIndexerDeclaration(node);
}
public override void VisitConditionalAccessExpression(ConditionalAccessExpressionSyntax node)
{
CSharp6Features = true;
base.VisitConditionalAccessExpression(node);
}
public override void VisitInterpolatedStringExpression(InterpolatedStringExpressionSyntax node)
{
CSharp6Features = true;
base.VisitInterpolatedStringExpression(node);
}
public override void VisitCatchFilterClause(CatchFilterClauseSyntax node)
{
CSharp6Features = true;
base.VisitCatchFilterClause(node);
}
}
Unfortunately it is not possible to detect whether the file written on 6 version or not based only on syntax checks because of some features are content-depended such as nameof
operator (it can be both special or usual method)
For testing C# 6 features you can use this file from ANTLR grammars repository.
Does C# 6.0 work for .NET 4.0?
Yes (mostly). C# 6.0 requires the new Roslyn compiler, but the new compiler can compile targeting older framework versions. That's only limited to new features that don't require support from the framework.
For example, while you can use the string interpolation feature in C# 6.0 with earlier versions of .Net (as it results in a call to string.Format
):
int i = 3;
string s = $"{i}";
You need .Net 4.6 to use it with IFormattable
as only the new framework version adds System.FormattableString
:
int i = 3;
IFormattable s = $"{i}";
The cases you mentioned don't need types from the framework to work. So the compiler is fully capable of supporting these features for old framework versions.
Differences in the new syntax of C# 6.0 / New null check syntax?
As it was alreay pointed out this C#6 feature is called Null-conditional Operators.
It's also worths looking into the generated C# code with ILSpy:
internal void onMyEvent(EventArgs eventArgs)
{
EventHandler expr_07 = this.MyEvent;
if (expr_07 != null)
{
expr_07(this, eventArgs);
}
}
As you see this is a pure compiler feature.. it just rewrites your code to the traditional null-check.
To answer you question (although I guess you already figured this out by looking at the code):
Wouldn't an Exception be thrown due to be invoking a method out of
null or the code stops executing if the expression before '?' is null?
There won't be an exception thrown when your eventhandler is null. The code just won't be executed when an object before the ? is null.
Now until this point this was only a method call. Obviously if you want to assign a value which is a result of an expression with a Null-conditional Operator it is a little bit more complicated: If it is a reference type then your variable remains null, but if it would be a value type then it will be automatically nullable and will be also null if the the object on which you use the '?' operator is null.
Here is a de-compiled code for this case:
Program.Customer[] array = new Program.Customer[10];
if (array == null)
{
int? arg_33_0 = null;
}
else
{
Program.Customer expr_1A = array[0];
if (expr_1A == null)
{
int? arg_33_0 = null;
}
else
{
new int?(expr_1A.IntField);
}
}
Is there any performance gain when using features from C# 6.0?
Not really. The new features are merely syntactic sugar for things already possible in C#.
The code generated by the new features, like the null-propagation operator, eventually yield the same C# code as you would already have had before.
It does make you better performing and possibly the code quality better, which is a good thing.
Using C# 6 features with CodeDomProvider (Roslyn)
The built-in CodeDOM provider doesn't support C# 6. Use this one instead:
https://www.nuget.org/packages/Microsoft.CodeDom.Providers.DotNetCompilerPlatform/
It's based on Roslyn and supports the C# 6 features.
Just change this line:
CodeDomProvider objCodeCompiler = CodeDomProvider.CreateProvider( "CSharp" );
to this:
CodeDomProvider objCodeCompiler = new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider();
Related Topics
Why Isn't Arraylist Marked [Obsolete]
Sqlconnection SQLcommand SQLdatareader Idisposable
How to Make the Value of a Variable Track the Value of Another
How to Create a Datatable in C# and How to Add Rows
How to Get the Time Difference Between Two Datetime Objects Using C#
How to Provide Custom Cast Support for My Class
How to Select an Option from Drop Down Using Selenium Webdriver C#
Directory.Getfiles of Certain Extension
Convert System.Drawing.Icon to System.Media.Imagesource
Sqlbulkcopy Insert with Identity Column
String Concatenation VS String Builder. Performance
Query Extremely Slow in Code But Fast in Ssms
C# Adding Button with Value at Runtime
Using ASP.NET Identity Database First Approach