Lets suppose if I have created a C# project which uses C# 4.0 features - optional parameter. What will happen if I select '.Net Framework 2.0' as a target framework? Will the compiler be intelligent enough to generate IL compatible with 2.0 on its own or will the Exe give runtime error when deployed on a machine that has only .Net framework 2.0?
In the specific case of optional parameters, compatibility will work as default values to use are stored in the caller's assembly and not in the called assembly so compatibility with other assemblies is ensured. If it compiles, it will run.
Optional parameters are just a syntaxic sugar. The following code compiles and run for a target framework 2.0 :
internal class Program
{
public static class DummyClass
{
public static string Bar(int b = 10, int a = 12)
{
return a.ToString();
}
}
private static void Main(string[] args)
{
Console.WriteLine("{0}", DummyClass.Bar(a: 8));
Console.ReadKey();
}
}
Read a full explanation by Mr Botelho
Related
I'm migrating project from mono to .NET Core and I'm using sqlite library.
Following code works as expected in Mono, but not in dotnet:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Sqlite version: " + Sqlite.LibVersionNumber());
}
}
public static class Sqlite
{
const string LibraryPath = "sqlite3";
[DllImport(LibraryPath, EntryPoint = "sqlite3_libversion_number", CallingConvention = CallingConvention.Cdecl)]
public static extern int LibVersionNumber();
}
Problem is, that in /usr/lib I have libsqlite3.so.0
If I rename (or create symlink in /usr/lib) to libsqlite3.so (without .0) everything works correctly in .NET Core.
Is there some switch to load also .so.0 libraries? Is it bug? Or expected feature?
You should allways have the .so and it should allways be a link.
How Do so (Shared Object) Filenames Work?
difference between .so.0 and .so.0.0.0 files
In my project, I've tried to tidy up the structure a bit and put all the C# classes into a separate folder (App_Code).
The problem is that it seems even if the project is set to use C# 7.1 (and .net framework 4.7)
Trying to create in subfolder class with newer syntax in example:
Namespace MyProject {
public static class Class1
{ (//*****Available since C# 6.0****)
public static string Test1 { get; } = ConfigurationManager.AppSettings["User"];
public static int Test2 ()
{
string s = "10";
int.TryParse(s, out int y); //*****Available since C# 7.0
return y;
}
}
This causes a compilation error stating, that this feature requires version 6.x (or 7.x in the case of "Test2" above) instead of 5.0.
Intelisense prompts me to change the version but even after following the prompt
the error persists.
Not sure if it matters, but classes in the App_Code folder have the same namespace as the ones in the rest of the project.
I use VS 2017 Pro.
I'm trying to reproduce the C# compiler error CS0840 with the exact code that's given in the website:
class Test36
{
public int myProp { get; } // CS0840
// to create a read-only property
// try the following line instead
public int myProp2 { get; private set; }
}
public Form1()
{
InitializeComponent();
Test36 test = new Test36();
}
I'm running it on .NET 4.0 using Visual Studio Community 2015. Surprisingly, I cannot reproduce it. Compiler doesn't throw any error:
Why the compiler isn't throwing any error?
You're using Visual Studio 2015, which implements C# 6. The fact that you're targeting .NET 4 is irrelevant - most of the C# 6 language features don't depend on framework features at all. The C# 6 code you're using can easily be compiled without reference to any modern CLR or framework features - it could have worked with .NET 1.0 if the language designers had decided to :)
You'll need to set you language level to C# 5 to see an error here. Do that in the project properties / Build / Advanced dialog:
You'll then get this error:
error CS8026: Feature 'readonly automatically implemented properties' is not available in C# 5. Please use language version 6 or greater.
Admittedly that's not the error you actually wanted to see - I think you'll need to use an earlier version of the compiler to get that exact error.
I guess it is because you are on Visual Studio 2015 with C# 6 which allows you to specify properties that are only set from the constructor (aka read-only properties).
See the following example:
class Test
{
public Test() // <-- this one does compile since it is the constructor
{
MyProp = 1;
}
public void SomeMethod() // <-- this one doesn't compile
{
MyProp = 1;
}
public int MyProp { get; } // <-- no CS0840 any more!
}
I am trying to use CallerMemberName attribute in .NET 4.0 via BCL portability pack. It is always returning an empty string instead of the member name. What am I doing wrong?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MessageBox.Show(new class2().CallMe);
}
}
public class class2
{
public string CallMe
{
get
{
return HelpMe();
}
}
private string HelpMe([CallerMemberName] string param = "")
{
return param;
}
}
Targeting 4.0 works just fine if you add:
namespace System.Runtime.CompilerServices {
sealed class CallerMemberNameAttribute : Attribute { }
}
I found the solution, though it's not useful to me. You need to install KB2468871 on top of .NET Framework 4 to be able to use caller info attributes. Unfortunately, I can't ask each developer to remember to install it when they setup development environment.
As I know, CallerMemberName is supported from .Net 4.5
You should not use it in .Net 4.0
Someone implemented this in .Net 4.0 using StackTrace. for example:
http://www.journeyintocode.com/2013/04/callermembername-net-40.html
BUT, I do NOT recommend you to use the StackTrace since there could be a performance hit.
Using StackTrace to get the caller name is very very slow. And this works in Debug, in release you cannot be sure whether StackTrace is "correct" or not.
So, my suggestion is: Just use CallerMemberName in .Net 4.5 or later version.
In the early version of .Net, there isn't any foolproof or fast way of doing this.
is it ok if i have this X project using .net2.0, and that X project is calling Y project which is using .net3.5.. i got customized buttons in Y project and im using that button in X project also, there's a method in Y project that has LINQ and X project is calling that method... i cant test it because i installed the latest .net framework.. :)
this is my code in project that has the .net3.5
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetDriveType(string lpRootPathName);
public enum DriveType : int
{
Unknown = 0,
NoRoot = 1,
Removable = 2,
Localdisk = 3,
Network = 4,
CD = 5,
RAMDrive = 6
}
var selectedDrives = from s in Environment.GetLogicalDrives() where Enum.GetName(typeof(DriveType), GetDriveType(s)).Equals(DriveType.Removable) select s;
foreach (String drives in selectedDrives)
{
MessageBox.Show(drives);
}
correct also the LINQ statement if i did it wrong.. :)
If the 3.5 framework is not installed on the machine that executes this, it will fail as System.Linq.dll won't exist. You can use LINQBridge with .NET 2.0 and C# 3.0 (which will give you access to a re-implementation of LINQ-to-Objects) but in reality it may be easier to get the client to upgrade. 2.0 is pretty old now.
Alternatively... if all you need is a where, there are easier routes. For example:
foreach (String drives in Environment.GetLogicalDrives())
{
if(!Enum.GetName(typeof(DriveType), GetDriveType(s))
.Equals(DriveType.Removable))
{
continue;
}
MessageBox.Show(drives);
}
A .NET 2.0 project cannot call a method in a .NET 3.5 project.