I'm noticing the compiler error The type '...' has no constructors defined generated when I erroneously attempt to instantiate a particlar class.
It lead me to wonder how I would go about writing my own class that would precipitate this message when someone attempted to instantiate it.
So the code below, what do I need to do to MyClass?
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
}
}
class MyClass
{
MyClass()
{
}
}
}
This error (CS0143) occurs if the class only defines an internal constructor and you try to instantiate it from another assembly.
public class MyClass
{
internal MyClass()
{
}
}
Also this error could be cause if you are compiling with Framework 4 or higher and embedding the Interop Types into your managed assembly. To get rid of this error you need to turn off (No embed) the Embedded Interop Types.
Instructions to turn off embedding:
On VS2010 Solution Explorer, right click on the Interop Reference that you are using.
Select Properties and look for Embed Interop Types
Change it from True to False
You can read about Embedded Interop Types here.
Pablo
I've managed to reproduce this by:
Creating a static class in a DLL
Using ildasm to decompile it to IL
Editing the IL to remove the "abstract" and "sealed" modifiers from the class
Rebuilding the DLL with ilasm
Compiling a program which tries to create an instance of the class
If you don't remove the abstract/sealed modifiers, the C# compiler recognizes it as a static class and gives a different error message. Of course, you could start off with a "normal" type and just remove the constructors, too.
EDIT: I actually thought I hadn't submitted this, as I saw the "internal" constructor one first. However, I'll leave it now as my version makes the C# compiler correct - there's a difference between a type having no accessible constructors and genuinely having no constructors :)
I believe you would need to make the constructor of the class internal in order to have it throw this exception. I believe you'll also need the class to exist in another assembly.
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
}
}
}
namespace DifferentNamespace
{
class MyClass
{
internal MyClass()
{
}
}
}
As has been said, you can get CS0143 by trying to instantiate a class with an internal constructor from outside its assembly.
But I believe it's a compiler bug. The error generated should be CS0122:
'member' is inaccessible due to its protection level
... which is the error you get if you try to instantiate a class with only a private constructor.
CS0143 used to happen (up to C# 3.0) if you tried to call a constructor for a built-in type like Double, but in C# 4.0 that now generates CS1729:
'type' does not contain a constructor that takes 'number' arguments.
if you pass an argument
Double d = new Double(1.25);
... or no error at all if you don't pass any arguments to the constructor.
Yet another option: the code might be right, but you might work on different projects in different instances of Visual Studio, and therefore you need to build the referenced project first.
Related
I just ran into the strangest thing and I'm a bit mind = blown at the moment...
The following program compiles fine but when you run it you get a RuntimeBinderException when you try to read Value. 'object' does not contain a definition for 'Value'
class Program
{
interface IContainer
{
int Value { get; }
}
class Factory
{
class Empty : IContainer
{
public int Value
{
get { return 0; }
}
}
static IContainer nullObj = new Empty();
public IContainer GetContainer()
{
return nullObj;
}
}
static void Main(string[] args)
{
dynamic factory = new Factory();
dynamic container = factory.GetContainer();
var num0 = container.Value; // WTF!? RuntimeBinderException, really?
}
}
Here's the mind blowing part. Move the nested type Factory+Empty outside of the Factory class, like so:
class Empty : IContainer
{
public int Value
{
get { return 0; }
}
}
class Factory...
And the program runs just fine, anyone care to explain why that is?
EDIT
In my adventure of coding I of course did something I should have thought about first. That's why you see me rambling a bit about the difference between class private and internal. This was because I had set the InternalsVisibleToAttribute which made my test project (which was consuming the bits in this instance) behave the way they did, which was all by design, although alluding me from the start.
Read Eric Lippert's answer for a good explanation of the rest.
What caught me really of guard was that the dynamic binder takes the visibility of the type of the instance in mind. I have a lot of JavaScript experience and as a JavaScript programmer where there really isn't such a thing as public or private, I was completely fooled by the fact that the visibility mattered, I mean after all, I was accessing this member as if it was of the public interface type (I thought dynamic was simply syntactic sugar for reflection) but the dynamic binder cannot make such an assumption unless you give it a hint, using a simple cast.
The fundamental principle of "dynamic" in C# is: at runtime do the type analysis of the expression as though the runtime type had been the compile time type. So let's see what would happen if we actually did that:
dynamic num0 = ((Program.Factory.Empty)container).Value;
That program would fail because Empty is not accessible. dynamic will not allow you to do an analysis that would have been illegal in the first place.
However, the runtime analyzer realizes this and decides to cheat a little. It asks itself "is there a base class of Empty that is accessible?" and the answer is obviously yes. So it decides to fall back to the base class and analyzes:
dynamic num0 = ((System.Object)container).Value;
Which fails because that program would give you an "object doesn't have a member called Value" error. Which is the error you are getting.
The dynamic analysis never says "oh, you must have meant"
dynamic num0 = ((Program.IContainer)container).Value;
because of course if that's what you had meant, that's what you would have written in the first place. Again, the purpose of dynamic is to answer the question what would have happened had the compiler known the runtime type, and casting to an interface doesn't give you the runtime type.
When you move Empty outside then the dynamic runtime analyzer pretends that you wrote:
dynamic num0 = ((Empty)container).Value;
And now Empty is accessible and the cast is legal, so you get the expected result.
UPDATE:
can compile that code into an assembly, reference this assembly and it will work if the Empty type is outside of the class which would make it internal by default
I am unable to reproduce the described behaviour. Let's try a little example:
public class Factory
{
public static Thing Create()
{
return new InternalThing();
}
}
public abstract class Thing {}
internal class InternalThing : Thing
{
public int Value {get; set;}
}
> csc /t:library bar.cs
class P
{
static void Main ()
{
System.Console.WriteLine(((dynamic)(Factory.Create())).Value);
}
}
> csc foo.cs /r:bar.dll
> foo
Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
'Thing' does not contain a definition for 'Value'
And you see how this works: the runtime binder has detected that InternalThing is internal to the foreign assembly, and therefore is inaccessible in foo.exe. So it falls back to the public base type, Thing, which is accessible but does not have the necessary property.
I'm unable to reproduce the behaviour you describe, and if you can reproduce it then you've found a bug. If you have a small repro of the bug I am happy to pass it along to my former colleagues.
I guess, at runtime, container method calls are just resolved in the private Empty class, which makes your code fail. As far as I know, dynamic can not be used to access private members (or public members of private class)
This should (of course) work :
var num0 = ((IContainer)container).Value;
Here, it is class Empty which is private : so you can not manipulate Empty instances outside of the declaring class (factory). That's why your code fails.
If Empty were internal, you would be able to manipulate its instances accross the whole assembly, (well, not really because Factory is private) making all dynamic calls allowed, and your code work.
I just ran into the strangest thing and I'm a bit mind = blown at the moment...
The following program compiles fine but when you run it you get a RuntimeBinderException when you try to read Value. 'object' does not contain a definition for 'Value'
class Program
{
interface IContainer
{
int Value { get; }
}
class Factory
{
class Empty : IContainer
{
public int Value
{
get { return 0; }
}
}
static IContainer nullObj = new Empty();
public IContainer GetContainer()
{
return nullObj;
}
}
static void Main(string[] args)
{
dynamic factory = new Factory();
dynamic container = factory.GetContainer();
var num0 = container.Value; // WTF!? RuntimeBinderException, really?
}
}
Here's the mind blowing part. Move the nested type Factory+Empty outside of the Factory class, like so:
class Empty : IContainer
{
public int Value
{
get { return 0; }
}
}
class Factory...
And the program runs just fine, anyone care to explain why that is?
EDIT
In my adventure of coding I of course did something I should have thought about first. That's why you see me rambling a bit about the difference between class private and internal. This was because I had set the InternalsVisibleToAttribute which made my test project (which was consuming the bits in this instance) behave the way they did, which was all by design, although alluding me from the start.
Read Eric Lippert's answer for a good explanation of the rest.
What caught me really of guard was that the dynamic binder takes the visibility of the type of the instance in mind. I have a lot of JavaScript experience and as a JavaScript programmer where there really isn't such a thing as public or private, I was completely fooled by the fact that the visibility mattered, I mean after all, I was accessing this member as if it was of the public interface type (I thought dynamic was simply syntactic sugar for reflection) but the dynamic binder cannot make such an assumption unless you give it a hint, using a simple cast.
The fundamental principle of "dynamic" in C# is: at runtime do the type analysis of the expression as though the runtime type had been the compile time type. So let's see what would happen if we actually did that:
dynamic num0 = ((Program.Factory.Empty)container).Value;
That program would fail because Empty is not accessible. dynamic will not allow you to do an analysis that would have been illegal in the first place.
However, the runtime analyzer realizes this and decides to cheat a little. It asks itself "is there a base class of Empty that is accessible?" and the answer is obviously yes. So it decides to fall back to the base class and analyzes:
dynamic num0 = ((System.Object)container).Value;
Which fails because that program would give you an "object doesn't have a member called Value" error. Which is the error you are getting.
The dynamic analysis never says "oh, you must have meant"
dynamic num0 = ((Program.IContainer)container).Value;
because of course if that's what you had meant, that's what you would have written in the first place. Again, the purpose of dynamic is to answer the question what would have happened had the compiler known the runtime type, and casting to an interface doesn't give you the runtime type.
When you move Empty outside then the dynamic runtime analyzer pretends that you wrote:
dynamic num0 = ((Empty)container).Value;
And now Empty is accessible and the cast is legal, so you get the expected result.
UPDATE:
can compile that code into an assembly, reference this assembly and it will work if the Empty type is outside of the class which would make it internal by default
I am unable to reproduce the described behaviour. Let's try a little example:
public class Factory
{
public static Thing Create()
{
return new InternalThing();
}
}
public abstract class Thing {}
internal class InternalThing : Thing
{
public int Value {get; set;}
}
> csc /t:library bar.cs
class P
{
static void Main ()
{
System.Console.WriteLine(((dynamic)(Factory.Create())).Value);
}
}
> csc foo.cs /r:bar.dll
> foo
Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:
'Thing' does not contain a definition for 'Value'
And you see how this works: the runtime binder has detected that InternalThing is internal to the foreign assembly, and therefore is inaccessible in foo.exe. So it falls back to the public base type, Thing, which is accessible but does not have the necessary property.
I'm unable to reproduce the behaviour you describe, and if you can reproduce it then you've found a bug. If you have a small repro of the bug I am happy to pass it along to my former colleagues.
I guess, at runtime, container method calls are just resolved in the private Empty class, which makes your code fail. As far as I know, dynamic can not be used to access private members (or public members of private class)
This should (of course) work :
var num0 = ((IContainer)container).Value;
Here, it is class Empty which is private : so you can not manipulate Empty instances outside of the declaring class (factory). That's why your code fails.
If Empty were internal, you would be able to manipulate its instances accross the whole assembly, (well, not really because Factory is private) making all dynamic calls allowed, and your code work.
I created the Class1.GetChild<T>() where T : DependencyObject extension method in lib1.dll assembly. After that, all assemblies that depends on lib1.dll failed to compile with error:
The type 'System.Windows.DependencyObject' is defined in an assemebly
that is not referenced. You must add a reference to assembly
'WindowsBase' etc...
Why dependent assemblies requires WindowsBase even if they don't use GetChild?
.
To reproduce (vs2010 .net4):
lib1.dll (references WindowsBase)
namespace lib1
{
public static class Class1
{
public static T GetChild<T>(this DependencyObject src) where T : DependencyObject
{
return default(T);
}
}
public static class Class2
{
public static int SomeExtMethod(this string src)
{
return 0;
}
}
}
lib2.dll (references lib1 but not WindowsBase)
using lib1;
class someClass
{
void someFct()
{
"foo".SomeExtMethod(); // error: The type 'System.Windows.DependencyObject'
// is defined in an assemebly that is not referenced.
// You must add a reference to assembly 'WindowsBase' etc..
}
}
.
Update:
I think there's definitly something when mixing generic methods and extension methods. I tried to demonstrate the issue in the following sample:
// lib0.dll
namespace lib0
{
public class Class0 { }
}
// lib1.dll
using lib0;
namespace lib1
{
public static class Class1
{
public static void methodA<T>() where T : Class0 { } // A
public static void methodB(Class0 e) { } // B
public static void methodC(this int src) { } // C
}
public static class Class2
{
public static void methodD(this String s) { }
}
}
// lib2.dll
using lib1;
class someClass
{
void someFct()
{
Class2.methodD(""); // always compile successfully
"".methodD(); // raise the 'must add reference to lib0' error depending on config. see details below.
}
}
A, //B, //C -> compile ok
A, B, //C -> compile ok
//A, B, C -> compile ok
A, //B, C -> raise error
A, B, C -> raise error
//A means methodA is commented. As Damien pointed out, type inference might play some role. Still curious to know the ins and outs.
Your situation has been answered by Microsoft here:
https://connect.microsoft.com/VisualStudio/feedback/details/668498/problem-with-extension-method-in-c-compiler
There are other use-cases as well independent of extension methods which produce this error wrongly.
Consider this:
Define a generic method in a type, say TP1, defined in library say LB1.
Type constrain the generic method on some type defined in some other library LB2.
Define another method in TP1.
Now in your library reference only LB1 and try to call the second method of type TP1
If you don't use TP1 but some other type defined in LB1, you do not get the error.
Also, even if one of the method of type TP1 expects a parameter of the type defined in LB2 (and you do not call this method) it does not produce this error
When one assembly depends on another assembly, the first assembly also depends on all the dependencies of the other--regardless of what is used. Assembly dependencies are effectively decoupled, another version of either assembly can be deployed after compilation, the compiler can't know that under circumstances like this one or more of the dependencies in the second assembly won't be used by the first assembly.
To solve the issue you can simply add a reference to WindowsBase.
Or, as prashanth points out, put the SomeExtMethod into a different assembly so code that uses that doesn't need to take a dependency on WindowsBase.
Update:
If you don't use anything from an assembly, you don't need any of its dependencies. But, as soon as you use one assembly, you need all the dependencies of that assembly as well. This is apparent in the way Visual Studio add references. If you add a reference to an assembly, it will copy all the dependent assemblies (not registered in the GAC) into your debug/release directories along with the assembly you added.
Update:
As to the compile error: that's the way it was written--there may be no other reason. Is it a good idea to get a compile error if you don't reference dependent assemblies? Maybe, you're likely to use something from a reference and that might use something directly from the references references--better a compile error than a deployment error.
Why not a compile error on every non-referenced secondary dependency? Again, it was written that way. Maybe an error here too would be good; but that would be a breaking change and would require really persuasive reasons.
I'm not sure this can be answered by anyone other than someone on the compiler team. I'm now thinking that it's to do with type inference - but whereas §7.6.5.1 Method Invocations talks about inference, §7.6.5.2 Extension method invocations is silent on the matter - despite the fact that inference obviously does take place when searching for applicable extension methods.
I think it's attempting some form of inference before it's performing the comparison on identifiers (which would immediately rule out the extension method since it's got the wrong name). Obviously, it can't perform any form of inference for this type if it's unable to understand the type constraints.
Hence, when you change your type constraint to just class, it now successfully passes over this method - it can infer a type parameter, but it now eliminates this extension method successfully.
When you reference another assembly, I assume the compiler needs to be able to parse any method signatures defined in that assembly, so it knows where to go to find that function if it sees a call to it.
If you replace your GetChild() function with
public static T GetChild<T>(this T src)
{
if (typeof(T) == typeof(DependencyObject)) return default(T);
else return default(T);
}
or something similar to that, it does not require you to include the reference to WindowsBase that you're running into. But if you add where T : DependencyObject to the signature, it does require it.
Effectively, you can use whatever assembly references you want in a project, so long as you don't expose them in any way. Once you expose them, then every other project which uses your library needs to be able to handle them, and thus requires those references themselves.
Maybe ILMerge would solve this problem. The idea is you create 2 dlls and merge them into one. That way you can have a single dll but reference it twice. Then way you can separate the GUI code from other code and only add the reference that you need to the particular project.
The answer is simple. It is because the method is decalre as public. This mean that it is visible to lib2.dll (in your case.) In other word you can call this method.
It also has a constrain that only classes inherited from DependencyObject can call this method. So that is the reason why you need to reference 'WindowsBase'.
I'm noticing the compiler error The type '...' has no constructors defined generated when I erroneously attempt to instantiate a particlar class.
It lead me to wonder how I would go about writing my own class that would precipitate this message when someone attempted to instantiate it.
So the code below, what do I need to do to MyClass?
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
}
}
class MyClass
{
MyClass()
{
}
}
}
This error (CS0143) occurs if the class only defines an internal constructor and you try to instantiate it from another assembly.
public class MyClass
{
internal MyClass()
{
}
}
Also this error could be cause if you are compiling with Framework 4 or higher and embedding the Interop Types into your managed assembly. To get rid of this error you need to turn off (No embed) the Embedded Interop Types.
Instructions to turn off embedding:
On VS2010 Solution Explorer, right click on the Interop Reference that you are using.
Select Properties and look for Embed Interop Types
Change it from True to False
You can read about Embedded Interop Types here.
Pablo
I've managed to reproduce this by:
Creating a static class in a DLL
Using ildasm to decompile it to IL
Editing the IL to remove the "abstract" and "sealed" modifiers from the class
Rebuilding the DLL with ilasm
Compiling a program which tries to create an instance of the class
If you don't remove the abstract/sealed modifiers, the C# compiler recognizes it as a static class and gives a different error message. Of course, you could start off with a "normal" type and just remove the constructors, too.
EDIT: I actually thought I hadn't submitted this, as I saw the "internal" constructor one first. However, I'll leave it now as my version makes the C# compiler correct - there's a difference between a type having no accessible constructors and genuinely having no constructors :)
I believe you would need to make the constructor of the class internal in order to have it throw this exception. I believe you'll also need the class to exist in another assembly.
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
}
}
}
namespace DifferentNamespace
{
class MyClass
{
internal MyClass()
{
}
}
}
As has been said, you can get CS0143 by trying to instantiate a class with an internal constructor from outside its assembly.
But I believe it's a compiler bug. The error generated should be CS0122:
'member' is inaccessible due to its protection level
... which is the error you get if you try to instantiate a class with only a private constructor.
CS0143 used to happen (up to C# 3.0) if you tried to call a constructor for a built-in type like Double, but in C# 4.0 that now generates CS1729:
'type' does not contain a constructor that takes 'number' arguments.
if you pass an argument
Double d = new Double(1.25);
... or no error at all if you don't pass any arguments to the constructor.
Yet another option: the code might be right, but you might work on different projects in different instances of Visual Studio, and therefore you need to build the referenced project first.
Sample code:
Below code is not complete but it is enough to show wt problem i am facing.
namespace ClassLibrary1
{
class Class1
{
internal static void sum(ref List<TestClass> a, int b)
{
//some code
}
}
}
There is another class in same assembly
namespace ClassLibrary1
{
class TestClass
{
//code
}
}
when I create unit test case for method sum then code would be like
[TestMethod()]
public void sumTest()
{
List<TestClass_Accessor> lstTestClass = new List<TestClass_Accessor>();
Class1_Accessor.sum(ref lstTestClass, b);
}
Problem: In above code I am creating list of type TestClass but it is private class so VSTS create TestClass_Accessor to access class functionality.
In method Sum, It takes parameter as a reference of list of type "TestClass".
I have also debug my code but when
Class1_Accessor.sum(ref lstTestClass, b); is debugged it throws exception "System.InvalidProgramException: JIT Compiler encountered an internal limitation ".
When i created list of string type then it works i.e. list has no problem.
As per my understanding problem is in type of list. in unit test we create list of type TestClass_Accessor.
And in class list has type List<TestClass>.
please provide solution for this.
Regards,
Nitin Sahu
I have problems understanding what You are saying. But...
TestClass is not private in code You provided. By default it is internal when no access modifier is specified. And You can easily access internal members in Your tests. Maybe You won't have any problems when You eliminate additional stuff (TestClass_Accessor).
Look here: How to test Framework if Unit tests are in separate assembly?
And BTW You don't need ref when passing reference values.
Using "ref" is part of the problem here. I had the same problem and it went away when not using the "ref" keyword.
As Peri already stated, using ref is not needed here.