I am observing a very strange behavior in my simple C# console application. I can't understand why CLR is working that way under the hood. Here are my code samples:
My Main program:
class Program
{
static void Main(string[] args)
{
Employee emp = new Employee();
Console.WriteLine( emp.EmployeeName());
}
}
The console application project containing the above Main method references another C# class library project named CustomDataObjects. It is as below:
namespace CustomDataObjects
{
public class Employee
{
public string GetEmployeeName()
{
return "Foo";
}
}
}
I build everything and it works perfectly fine. Main function prints "Foo" on console.
Now I changed my CustomDataObjects project as below. I changed the signature of GetEmployeeName method and introduced a new mandatory parameter named empName
namespace CustomDataObjects
{
public class Employee
{
public string GetEmployeeName(string empName)
{
return empName;
}
}
}
I did not recompile my console project after making these changes. I simply recompiled CustomDataObjects project after making above changes. Then, I copied the newly built CustomDataObjects.dll and CustomDataObjects.pdb files into \bin\debug directory of main console project.
Now I try to run the executable file of main console application from bin\debug directory of main console project. To my surprise it doesn't crash. If I'm not wrong, on the second run CLR should have tried to look for definition of GetEmployeeName with older signature which doesn't have any parameter and since CustomDataObjects.dll has changed it should observe the mismatch and cause a run-time crash. Why did it not happen this way? My console application is running on .Net v4.0
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!
}
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
The main.cs of my project returns the following warning:
Warning 1 The type 'Extensions.MessageDetails' in 'PATH\Extensions.cs' conflicts with the imported type 'Extensions.MessageDetails' in 'path\lib.dll'. Using the type defined in 'path\Extensions.cs'. path\main.cs
What is wrong with my project? How to get rid of the warning?
The code of my project has the following structure:
Extensions.cs
namespace Extensions
{
public class MessageDetails
{
public string message { get; set; }
public string link { get; set; }
public string picture { get; set; }
public string name { get; set; }
public string caption { get; set; }
public string description { get; set; }
public string userid { get; set; }
public string username { get; set; }
public object actions { get; set; }
public object privacy { get; set; }
public object targeting { get; set; }
}
}
lib.dll
namespace MyClassLib {
public class MyClassLibFoo {
public void foo(MessageDetails parameters) {
/* .. */
}
}
}
main.cs
using MyClassLib;
using Extensions;
class Program
{
static void Main(string[] args)
{
MessageDetails md = new MessageDetails();
}
}
In my case, with Visual Studio 2013, I found that one of my class libraries had developed a reference to itself. I think it happened when I added a new project to my solution or it was a bug, but either way it was causing this exact issue.
Check your project references for any circular references.
It seems like Extensions.cs is both part of the project that builds lib.dll and your main.exe
Remove it from one of the project to fix this issue.
I had this kind of issue where I had reverted from a target .NET Framework version of 4.5.2 to 4.0.
Classes in my App_Code folder had methods that called methods in other classes in that folder. When I created a standard folder I named "AppCode", and moved my classes into it, I no longer had the issue.
If I re-created the "App_Code" folder and move my classes back into it, I will have this issue again. I'm convinced it has to do with my .NET Framework version or that Visual Studio just doesn't deal well with changing it after being initially built/targeted to another version.
You can't have two copies of the extensions class, even though the code is the same they are not seen as the same object. Both your dll and main application will need to reference the exact same one.
You could try creating a 'Common Files' class library and add the extensions class to it, that way you will always be using the correct class
I had this problem with a project that is also hosted on NuGet. I checked all project references. Finally, the object browser revealed that the DLL of an older version of my NuGet package was somehow loaded in Visual Studio from the NuGet cache folder ("C:\Users\{username}\.nuget\packages"). I removed the package from the cache folder, it disappeared from the object browser and everything was working fine again.
I had a Shared Project, "Project A," which was included in both "Project B" and "Project C."
"Project A" was added as a Shared Project in "Project B" and "Project C."
"Project A" also included a traditional reference to "Project B."
To correct the problem, I removed the reference to "Project B" from "Project A."
If you really need to have both classes declared or referenced in two separate dll, you can mark your class as internal.
Internal types or members are accessible only within files in the same assembly, therefore it will prevent the collision.
After reading through many answers on SO the solution was still unclear. My situation was similar but the solution was found by:
Example project Name: My.Example.Project
Opening my project
Open the References dropdown
Finding My.Example.Project in the References section
Deleting the reference to My.Example.Project
That fixed it!
I had faced same problem. Just a simple solution for that.
Check your project references there must be same project reference. just remove that, it will work.
sometimes I get this error - it's a bug though in my case.. All I have to do to fix it is change the first letter of my script file name from upper case to lowercase in the file in Explorer /
(or in Unity Engine in my case)
and then change the name / class accordingly in my script. Idk why this happens.. just does - and Idk why this fix works .. but in my case it always does. - Otherwise you probably have 2 copies of the same script / same class name for 2 diff scripts. Hope this helps.
I fixed this error by deleting the .suo file in the directory sturcture vs directory. stop vs then delete restart vs. that worked for me.
I created my custom DLL "MongoDbExtensions". Now in a new project I add a reference to the "MongoDbExtensions" and then try to invoke a method inside the MongoDbExtensions called ToDocument. I use resharper to add the namespace at the top of the file but when I compile I still get the following error:
Error 1 The type or namespace name 'MongoDbExtensions' could not be found (are you missing a using directive or an assembly reference?) C:\Projects\HelpForum\DemoConsole\Program.cs 6 7 DemoConsole
What is going wrong? My DLL can be downloaded from here:
http://github.com/azamsharp/MongoDbExtensions/downloads
UPDATE 1:
Here is the MongoExtensions class:
namespace MongoDbExtensions
{
public static class MongoExtensions
{
public static List<T> ToList<T>(this IEnumerable<Document> documents)
{
var list = new List<T>();
var enumerator = documents.GetEnumerator();
while (enumerator.MoveNext())
{
list.Add(enumerator.Current.ToClass<T>());
}
return list;
}
}
}
ToDocument is an extension method that works on Object.
I repro. This DLL was built targeting .NET 4.0. You cannot use it in a project that targets anything else but the full 4.0 .NET framework. Either targeting a lower version or the client profile will produce this error.
Since your class is called MongoExtensions, you need to change MongoDbExtensions in your test project source code to MongoExtensions.