what is the default constructor access modifer? - c#

I am confuse on what is the default constructor access modifier and what does this MSDN statemtn says
If the direct base class does not have an accessible parameterless instance constructor, a compile-time error occurs.
Because when i applied this with a test program it fails. I can make an object or class that is inheriting another class thogh there is no exteranal parameerless constructor defined.
class A
{
}
class B : A
{
}
class C
{
public void main()
{
B objB = new B();// as per MSDN here should be the compile time error.
}
}
[Source]

If the direct base class does not have an accessible parameterless
instance constructor, a compile-time error occurs.
If a constructor is not defined for a class, the compiler will automatically generate a public default constructor.

If a class contains no instance constructor declarations, a default
instance constructor is automatically provided. That default
constructor simply invokes the parameterless constructor of the direct
base class. If the direct base class does not have an accessible
parameterless instance constructor, a compile-time error occurs. If
the class is abstract then the declared accessibility for the default
constructor is protected. Otherwise, the declared accessibility for
the default constructor is public.
In your example, all the classes A, B, C has been created with a default internal parameterless constructor.
Since both classes are in the same assembly and are internal with internal constructors by default you are not getting a compilation error. But if you declare a non-accessible constructor (e.g. private or protected) in your class B you will get a compilation error in your example.

The compiler creates parameterless constructor if you don't create one yourself, so as per the MSDN page, your example actually ends up looking like this;
class A
{
public A(): base() {}
}
class B : A
{
public B(): base() {}
}
Your call to new B() will ultimately end up calling A's constructor. However, if you created an explicit constructor for A which is private;
class A
{
private A() {}
}
class B : A
{
}
Then this translates to;
class A
{
private A() {}
}
class B : A
{
public B(): base() {}
}
Which will fail to compile with an error about A's constructor being inaccessible.

If a constructor is not defined for a class, the compiler will automatically generate a public default constructor.
However, if there is a constructor defined that limits the access, then the compiler will throw.
for example, this should throw an exception:
class A
{
private A() {}
}
class B : A
{
}

From Using Constructors
Unless the class is static, classes without constructors are
given a public default constructor by the C# compiler in order to
enable class instantiation.

Related

Can't derive class from abstract System.Drawing.Image class [duplicate]

I want to inherit a class from another class, marked as abstract, that not have any constructor defined.
This is my code:
// In one assembly (TheMessage.dll), as seen via F12 in VS (from Metadata)
namespace Namespace1
{
public abstract class Message
{
public string Body { get; set; }
// some abstract methods here, not shown.
}
}
// In another assembly (TheUser.dll)
namespace Namespace2
{
public class MyMessage : Namespace1.Message
{
public MyMessage()
{
}
}
}
The problem is that on the public MyMessage() constructor I get the error
The type 'Namespace1.Message' has no constructors defined
I saw on MSDN site (abstract (C# Reference) first example) that inheriting an abstract class without constructor is possible. So, anyone know why I get this error?
Note that one can inherit just fine when type is in the same DLL as the Message class and it works as that assembly exposes some other types deriving from Namespace1.Message similar to following:
// The same assembly as Message (TheMessage.dll), as seen via F12 in VS (from Metadata)
namespace Namespace3
{
public class Message : Namespace1.Message
{
public Message() {}
public Message(string to) {}
}
}
I've also checked The type '...' has no constructors defined, but it does not speak about inheritance but rather just new-ing up an instance and I clearly have no expectations to directly instantiate an instance of an abstract class.
You probably have an internal constructor (not shown in the code that you posted) and are trying to instantiate the class with the internal constructor from a different assembly.
(The default constructor for a base class is automatically called from a derived class if you don't explicitly specify a base class constructor to call, so it might not be obvious to you that the base class constructor is being called.)
For example, if one assembly contains this class (inside namespace ClassLibrary1):
public class Base
{
internal Base()
{
}
}
And a DIFFERENT assembly does this:
class Derived: Base
{
public Derived()
{
}
}
You will see the following compile error:
The type 'ClassLibrary1.Base' has no constructors defined
If none of the instance constructors of the Message class are visible to you (typically because they are all private and you are outside the class, or they are all private or internal and you are outside the assembly), you cannot write a class that inherits from Message. (Well, you could make two instance constructors which chain each other cyclicly with the :this(...) syntax, but that would not be useful).
Note that when you look at the "metadata" (reflection generated pseudo-C# for an assembly you refer), you typically only see the "visible" members, so any private or internal members will not show up. I think you look at the metadata because we see non-abstract (and non-extern) methods whoses bodies are absent (just a semicolon ; there instead of a body { ... }).
The source code of your Message class will have one or more constructors, each private or internal, but when seen from outside the assembly, these are "non-existent".
If the source code of a non-static C# class Message contains no instance constructors, the compiler will generate one automatically. It will be a public parameterless constructor if the class is concrete (i.e. non-abstratc), and a protected one if the class is abstract.
That means that if the source code looks like this:
public abstract class Message
{
// note: zero non-static constructors here
}
it will be compiled exactly as if it had said:
public abstract class Message
{
protected Message()
{
}
}
and in that case the generated instance constructor is accessible to all classes deriving from Message.

Abstract class with constructor, force inherited class to call it

I have an abstract class with constructor XYZ(string name).
Also I have a class that inherits from that abstract class.
How to force inherited class to call base(string name)?
Now I can use new Inherited() and it will not call base constructor. I want to force user to implement default constructor in inherited class.
A class without an explicit constructor has a parameterless constructor. In the other hand, if you implement a constructor with parameters and no paramterless constructor, your class won't be instantiable without arguments.
In other words:
public abstract class A
{
public A(string x)
{
}
}
public class B : A
{
// If you don't add ": base(x)"
// your code won't compile, because A has a
// constructor with parameters!
public B(string x) : base(x)
{
}
}
That is, if A has a parameterless constructor (or no explicit constructor), B will automatically call the base constructor. You don't need to code any further stuff here.
Otherwise, if your base class has a parameterless constructor and a constructor with parameters, you can't force a derived class to automatically call a constructor excepting the default one (i.e. the so-called parameterless constructor).
Workaround
Well, there's no special workaround here, but be aware C# supports optional parameters in both constructors and methods.
If you want to be 100% sure derived classes will call a concrete base constructor, you can implement your base class using a single parameterless constructor with optional parameters and use this instead of constructor overloading:
public class A
{
public A(string x = "hello world") // or just string x = null
{
}
}
Now if a B class derived A, B will always call A's base constructor, since x is optional and it has a default value.
How to force inherited class to call base(string name)
Make parameterless constructor in your abstract class private, or not add it at all. That's will force all derived classes to call the constructor you specified or there will be a compile error.
public abstract class BaseClass
{
protected BaseClass(string parameter)
{
}
}
public class DerivedClass : BaseClass
{
public DerivedClass()
{
}
}
Will end up with
'`Project.BaseClass`' does not contain a constructor that takes 0 arguments
You don't need to do anything. All derived class constructors must call a base class constructor (except for some particularly evil hacks, that you probably don't need to worry about). If none is explicitly specified in code, an implicit call to the base class's parameterless constructor is implied. If the base class has no parameterless constructor (as is the case if you add a constructor accepting a string and don't explicitly add a parameterless constructor), the class will not compile.
I have spent the last half hour or so experimenting once again with permutations of an abstract base class that has its default constructor marked as private and an overload that takes 4 parameters, and a derived class that has only the 4-parameter overload. Using the latest C# compiler (7.3), it is evident that in this situation:
The derived class must explicitly define the 4-parameter overload.
The overload in the derived class call to the 4-parameter overload must be explicit.
Base Class Constructor Signature
public OperatingParameterBase (
string pstrInternalName ,
string pstrDisplayName ,
T penmParameterType ,
U penmDefaultParameterSource )
Derived Class Constructor
internal OperatingParameter (
string pstrInternalName ,
string pstrDisplayName ,
T penmParameterType ,
U penmDefaultParameterSource )
: base (
pstrInternalName ,
pstrDisplayName ,
penmParameterType ,
penmDefaultParameterSource )
{
} // internal OperatingParameterExample constructor
I showed the whole constructor in the derived class to demonstrate that calling the base class constructor is its only absolute requirement. Since the work of the base constructor is irrelevant to this discussion, I left it out.

Derived class explicit base constructor call

I am trying to learn C#. The below data is from a Microsoft C# help website.
I don't understand this statement, "If a base class does not offer a default constructor, the derived class must make an explicit call to a base constructor by using base."
I thought that if there is no default constructor for a class, C# will automatically assign default values to int, char or whatever is declared in a class. If a base class does not have a constructor and it has a child class, does the rule mentioned in the last sentence not apply? Please clarify.
In a derived class, if a base-class constructor is not called explicitly by using the base keyword, the default constructor, if there is one, is called implicitly. This means that the following constructor declarations are effectively the same:
C#
public Manager(int initialdata)
{
//Add further instructions here.
}
C#
public Manager(int initialdata)
: base()
{
//Add further instructions here.
}
If a base class does not offer a default constructor, the derived class must make an explicit call to a base constructor by using base.
If you do not define a constructor for a class:
public class DemoClass
{
public void SomeFunction() { }
}
C# will add a default (parameterless) constructor for you. In this case; nothing special needs to be done with derived classes, as they will use the provided default constructor. Of course, you can always define your own default (parameterless) constructor:
public class DemoClass
{
public void DemoClass() { }
public void SomeFunction() { }
}
Which still doesn't require anything special for derived classes, since they can still use it. If however, you define a parameterized constructor, without defining a default:
public class DemoClass
{
public void DemoClass(string argument) { }
public void SomeFunction() { }
}
Now there is no default (parameterless) constructor for derived classes to use; and you need to say which constructor to use with base:
public class DerivedClass : DemoClass
{
public DerivedClass() : base(String.Empty) { }
}

Inheritance constructor issue

I'm having a slight issue with some inheritance.
In my base class I have the following constructor:
public Camera(string n)
{
name = n;
}
Then in my child class I have the following constructor:
public StereoCameras(string n)
{
name = n;
}
How ever, my child class complains it does not contain a constructor that takes 0 arguments. I'm fairly new to using inheritance like this, and I thought I had set up my childs constructor properly.
Is there something I'm missing?
You will need to invoke the base constructor:
public StereoCameras(string n) : base(n)
{
}
Then the assignment in the derived class is redundant.
Your child class constructor call is equivalent to:
public StereoCameras(string n) : base()
since you have not defined any parameter less constructor in your base class, hence the error. Base class's parameter less constructor is called implicitly (if none is called using base keyword)
See: Using Constructors (C# Programming Guide) - MSDN
In a derived class, if a base-class constructor is not called
explicitly by using the base keyword, the default constructor, if
there is one, is called implicitly
To come over the problem you can either declare a parameter less constructor in base class or call the defined constructor explictily like:
public StereoCameras(string n) : base(n)
Also from the same link
If a base class does not offer a default constructor, the derived
class must make an explicit call to a base constructor by using
base.
Use
public StereoCameras(string n) : base(n)
{
}
When a class is instantiated the constructor of the base-class is always invoked before the constructor of the derived class. If the base class does not contain a default constructor you must explicitly define how to call the constructor of the base class.
In your case this would be (note the base call)
public StereoCameras(string n)
: base(n)
{
}
Just add a constructor without any parameter to the base class. This will solve your issue.
public Camera()
{
}

C#: constructor of nested class makes "inaccessible due to protection level"

I have this piece of code, and error is generated, just because I haved added into a constructor for its class.
class NestedClass
{
class A
{
A() {}
}
class B
{
// no constructor
}
public static void run()
{
A a = new A(); // error
B b = new B(); // no error
}
}
And error is:
NestedExample.A is inaccessible due to protection level
Please help me explain this.
Thanks :)
Your constructor is private. Default access modifier for class members is private.
class A
{
A() {}
}
this is correct implementation
class A
{
public A() {}
}
Define your constructor as public
public A() { }
Your constructor for class A is private
Private Constructors (C# Programming Guide) - MSDN
Note that if you don't use an access modifier with the constructor it
will still be private by default.
The reason it is working for B is that you haven't specified any constructor and for default constructor:
Constructor - MSDN
Unless the class is static, classes without constructors are given a
public default constructor by the C# compiler in order to enable class instantiation
Define the constructor as public
public class A
{
public A() {}
}
Your constructor of A is private. It cannot be accessed from outside of A.
At the same time, B does not have a consuctor at all and therefore gets a default public constructor.
you need to specify, the default one is private and while in the case of B the compiler provides a public parameterless constructor for you., so you have to specify it for class A
class A
{
public A() { }
}
Make your nested classes public and the problem will be solved. Your run method is public but the classes you want to use are not public and this gives problems.

Categories