Instantiate a class (or derived) with internal constructor - c#

let's say I have a class defined in an assembly with:
public class BaseClass
{
internal BaseClass()
{
}
}
And in another assembly, I would like to instanciate this class with :
BaseClass c = new BaseClass();
I get the CS0143 error.
Trying another way, I try to create a derived class of the first one :
public class DerivedClass : BaseClass
{
}
but same error.
The BaseClass is not sealed. How can I instantiate this class or a derived one? Of course, I can't modify the BaseClass.

You'll have to use reflection to get the internal constructor and invoke it:
var ci = typeof(BaseClass).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
var instance = (BaseClass)ci.Invoke(new object[0]);
Since the existence of the constructor is only discovered at run-time, this approach will break if the constructor of BaseClass is changed or removed.

1) You want an actual instance of the base class:
There needs to be some method in the assembly that it's in that constructs it for you. This would normally be called a "factory". It might look like this:
public class BaseFactory
{
public static BaseClass Create() { return new BaseClass(); } //may also add other creation logic
}
Note that such a creation method may even be in BaseClass itself, or it could be in another class. (If the constructor was private it would need to be in the class itself.)
2) You want an instance of the derived class. (Perhaps you're not supposed to be able to construct the base class. If this is true it probably should be abstract.)
public class Derived : BaseClass { }
public class Foo
{
public void Bar() { Derived d = new Derived();}
}

It's hard to tell from your question if DerivedClass is in the same assembly as BaseClass. If it is, just instantiate the derived class:
BaseClass c = new DerivedClass();
And, like Branko stated, if you have control of the project in which BaseClass lives, you can use InternalsVisibleTo.

Related

Inheriting constructor with single optional argument

I have a set of classes that inherit from a base...
public abstract class BaseClass
{
public BaseClass()
{
// ...
}
}
public abstract class BaseMessageClass : BaseClass
{
// ...
}
public SpecificMessageClass : BaseMessageClass
{
// ...
}
Instantiating an object like this works:
SpecificMessageClass myMessage = new SpecificMessageClass();
However, I need to change all constructors to have an optional string parameter, like this:
public abstract class BaseClass
{
public BaseClass(string optParam="whatever")
{
// ...
}
}
Now, when I try and instantiate the object with the optional argument:
SpecificMessageClass myMessage = new SpecificMessageClass("coolstring");
I get the error:
'SpecificMessageClass' does not contain a constructor that takes 1 arguments"
Is there ANY way to do this without explicitly declaring the constructors in each level of inherited class?
No.
But given that you want to inherit, I'm guessing you want the same logic to apply at all levels on some inherited field or property. If so, the closest you can get is to add a factory method like a Create<T>(string optParam="whatever") on the base class like the following:
public class BaseClass
{
public static T Create<T>(string optParam="whatever") where T : BaseClass
{
var t = new T(); //which invokes the paramterless constructor
((BaseClass)t).SomePropertyOrFieldInheritedFromTheBaseClass = optParam; //and then modifies the object however your BaseClass constructor was going to.
return t;
}
}
That would allow all implementers of the class to implement the BaseClass and get the same effect as having the optional parameter constructor.
By the way, I didn't test the above code, so you might need to tweak it slightly. But hopefully it gives the idea.
I think that's probably the closest you can get.
Constructors are special methods. If your class specifies no constructors, it will have a no-args constructor that inherits from the parent's no-args constructor. As soon as you specify a single constructor, you do not automatically get any of the parent's constructors for free. You must declare each different constructor you need.

Make base class method use new child field

I have a class with a method that calls a method on an object which is hidden in the class which inherits it (but the new field is inherited from baseField as well), and I need calls to this method to take place on the new field but when I call childClass.doSomething() I get an exception saying baseField is null.
I think this is because baseField in baseClass is being accessed, which hasn't been instantiated but I'm not really sure
How can I get someMethod to use the ExtendedBaseField when accessed from childClass
public abstract class baseClass{
protected BaseField baseField;
public void someMethod(){
baseField.doSomething()
}
}
And a class that inherits it:
public class childClass : baseClass{
protected new ExtendedBaseField baseField = new ExtendedBaseField();
}
new childClass().someMethod(); //null pointer exception
ExtendedBaseField inherits BaseField
You're using the new keyword which creates a new field, not set the old one. I am against making fields protected, they should be properties. also you should camel case all properties, methods and classes in .NET. Also brackets should go on their own line.
As per your comments you wanted typed access on your new type so you should make your base class generic. I have demonstrated that as well.
public abstract class BaseClass<T>
where T: BaseField
{
protected BaseClass(T baseField)
{
this.BaseField = baseField;
}
protected T BaseField{get; private set;};
public void SomeMethod()
{
BaseField.DoSomething()
}
}
public class ChildClass : BaseClass<ExtendedBaseField>
{
public ChildClass() : base(new ExtendedBaseField())
{
}
}
Others have given the correct technical answer: You're explicitly hiding the field in the base class.
I'll speak to the bad practice here, instead.
In C++, there's the concept of RAII. Resource Allocation Is Initialization. In C#, we don't generally have to think of resource allocation the same way we do in C++, but the pattern of RAII is still a good practice.
All fields declared in a class should be initialized inline
protected BaseField baseField = new BaseField();
...or in the constructor for that class
protected BaseField baseField;
public BaseClass<T>()
{
this.baseField = new BaseField();
}
If that is not possible, then use an abstract property instead of a field, which forces the child class to implement and initialize it.
protected abstract BaseField BaseField { get; }
The child class is hiding baseField:
protected new ExtendedBaseField baseField = new ExtendedBaseField();
This creates a new baseField property, so the child class can no longer see the base class' baseField property. Thus, it's never set. Thus, it's null.
Don't hide the base class' field. If you want the base class to use it, have the child class use it to:
public class childClass : baseClass {
public childClass() {
baseField = new ExtendedBaseField();
}
}

Why can't we use a constructor with parameter in derived classes

Why is this not possible?
I get the following compiler-error when instantiating "DerivedClass" with a constructor-parameter:
'GenericParameterizedConstructor.DerivedClass' does not contain a constructor that takes 1 argument
But calling a very similar method works.
Why?
class Program
{
static void Main(string[] args)
{
// This one produces a compile error
// DerivedClass cls = new DerivedClass("Some value");
// This one works;
DerivedClass cls2 = new DerivedClass();
cls2.SomeMethod("Some value");
}
}
public class BaseClass<T>
{
internal T Value;
public BaseClass()
{
}
public BaseClass(T value)
{
this.Value = value;
}
public void SomeMethod(T value)
{
this.Value = value;
}
}
public class DerivedClass : BaseClass<String>
{
}
Constructors aren't inherited - it's as simple as that. DerivedClass contains a single constructor - the public parameterless constructor provided by default by the compiler, because you haven't specified any constructors.
Note that this has nothing to do with generics. You'd see the same thing if BaseClass weren't generic.
It's easy to provide constructors for DerivedClass though:
public class DerivedClass : BaseClass<String>
{
public DerivedClass() : base()
{
}
public DerivedClass(string value) : base(value)
{
}
}
The deriving class needs to expose the constructor
public class DerivedClass : BaseClass<String>
{
public DerivedClass(string str) :base(str) {}
}
It would sometimes be helpful if there a way of instructing the compiler to automatically generate for a particular derived class constructors which precisely mimic and wrap all those of the base class. Having such behavior occur by default, however, would be problematic. Many derived classes expect that some of their code will be called whenever an instance of their type is created. Suppose a parent type had two constructors:
parentType(int foo) {...}
parentType(string foo) {...}
and a derived type had one:
derivedType(string foo) {...}
What should be the effect of new derivedType(7);? The compiler would know how to create a new baseType(7);, but if it created a new "blank" derivedType object and then simply called the parent-type constructor, the result would be a derivedType object which had never run any of derivedType's construction code. While some classes wouldn't have any problem with that (and for such classes, the earlier-mentioned hypothetical feature would be helpful), a lot of classes would.
Incidentally, a somewhat-related issue occurs with protected constructors. In some .net languages including at least the current version of C#, if non-abstract type Foo defines a protected constructor, that constructor may only be used to create instances of derived types. In other languages, including the current vb.net, it's possible for code within a derived type to call a protected constructor of the base type to create a new base-type instance.

How to prevent inherited classes instances

I want to force any class not to be able to create a new instance if it inherits a specific base class, so how this base class should look like?
The following code is in java. just to give you an Example
Base class has an exception on the constructor.
public class BaseClass
{
public BaseClass()
{
throw new AssertionError();
}
}
The child class extending the base class but if you create an object of it it will give u an exception.
public class MainClass extends BaseClass
{
public MainClass()
{
}
public static void main(String[] args) {
MainClass c = new MainClass();
}
}
You want to seal your base class.
public sealed class BaseClass
{
public BaseClass(){};
}
public class SubClass : BaseClass
{
public SubClass(){};
}
This will throw a compiler error because you cannot inherit from a sealed base.
You can't specify that in the baseclass, any deriving class is self responseable, if it wants to present the ability to be derived from, than you can't do anything about it.
you can declare the base class as const - that way other classes cant extend it.
You can't do this. Please specify why you want to do this.

Get derived class type from a base's class static method

i would like to get the type of the derived class from a static method of its base class.
How can this be accomplished?
Thanks!
class BaseClass {
static void Ping () {
Type t = this.GetType(); // should be DerivedClass, but it is not possible with a static method
}
}
class DerivedClass : BaseClass {}
// somewhere in the code
DerivedClass.Ping();
This can be accomplished easily using the curiously recurring template pattern
class BaseClass<T>
where T : BaseClass<T>
{
static void SomeMethod() {
var t = typeof(T); // gets type of derived class
}
}
class DerivedClass : BaseClass<DerivedClass> {}
call the method:
DerivedClass.SomeMethod();
This solution adds a small amount of boilerplate overhead because you have to template the base class with the derived class.
It's also restrictive if your inheritance tree has more than two levels. In this case, you will have to choose whether to pass through the template argument or impose the current type on its children with respect to calls to your static method.
And by templates I, of course, mean generics.
If I'm not mistaken, the code emitted for BaseClass.Ping() and DerivedClass.Ping() is the same, so making the method static without giving it any arguments won't work. Try passing the type as an argument or through a generic type parameter (on which you can enforce an inheritance constraint).
class BaseClass {
static void Ping<T>() where T : BaseClass {
Type t = typeof(T);
}
}
You would call it like this:
BaseClass.Ping<DerivedClass>();
A static method is defined on the type. There is no "this". You'll need to make this an instance method, instead:
class BaseClass {
public void Ping() {
Type t = this.GetType(); // This will work, since "this" has meaning here...
}
You can then do:
class DerivedClass : BaseClass {}
DerivedClass instance = new DerivedClass();
instance.Ping();
In short this is what I tried to answer here. It uses one interface to unify all derived classes and let them all call the same static method from the base class without passing a Type.
public interface IDerived
{
}
public class BaseClass<T> where T : IDerived
{
public static void Ping()
{
//here you have T = the derived type
}
}
public class DerivedClass : BaseClass<DerivedClass>, IDerived
{
//with : BaseClass<DerivedClass> we are defining the T above
}
public class ExampleApp
{
public void Main()
{
//here we can call the BaseClass's static method through DerivedClass
//and it will know what Type calls it
DerivedClass.Ping();
}
}
Just a guess (not tested)
Type t = MethodBase.GetCurrentMethod().DeclaringType;
It's not possible to get the derived class from a static method. As an example to illustrate why, imagine BaseClass has 2 subclasses - DerivedClass and AnotherDerivedClass - which one should be returned? Unlike polymorphic non-static methods, there is no possible association with a derived class calling a static method on a base class - the compile time type and runtime type are the same with a static method call.
You can either make the method non-static, so you then get the correct type via polymorphism, or create static method "overrides" in the subclasses, e.g.
class DerivedClass : BaseClass
{
void Ping() {
BaseClass.Ping();
// or alternatively
BaseClass.Ping(Type.GetType("DerivedClass"));
}
}
Your client code can then call the method in the derived class to explicitly indicate it want's the derived class version. If necessary, you might then also pass the DerivedClass type as a parameter to the base class method, to provide context that the method was called via the derived class.
Why not just use the methods that are there already?
If you have
class BaseClass {}
partial class DerivedClass : BaseClass {}
You can look at
DerivedClass.GetType().BaseType;
I think the following will work for this case (and several similar ones elsewhere on SO). Perf won't be too good, but if this is infrequent, that won't be a problem.
Create a stacktrace and parse it looking for a derived class. In the general case this wouldn't be too reliable or might not even work, but in specific cases, like that in the OP, I believe this will work fine. In Powershell:
$strace = (new-object diagnostics.stacktrace).tostring()
#
$frames = $strace -split " at "
$typesFromFrames = $frames | select -skip 1| # skip blank line at the beginning
% { ($_ -split "\(",2)[0]} | # Get rid of parameters string
% {$_.substring(0,$_.lastindexof("."))} | # Get rid of method name
$ {$_ -as [type]}
#
# In powershell a lot of the frames on the stack have private classes
# So $typesFromFrames.count is quite a bit smaller than $frames.count
# For the OP, I don't think this will be a problem because:
# 1. PS isn't being used
# 2. The derived class in the OP isn't private
# (if it is then tweaks will be needed)
#
$derivedOnStack = $typesFromFrames | ? { $_.issubclassof( [BaseClass])}
Hopefully there will just be one element in $derivedOnStack, but it will depend on the particulars of the application. Some experimentation will be required.

Categories

Resources