Inheriting Constructors? - c#

Is it possible to inherit constructors, and if so, how?
I am trying to make a class that inherits a System class, and I want the constructors of it.

This is not possible in vanilla C#. Constructors can't be simply inheritted. They must be redefined on every level and then chained to the parent's version.
class Parent {
internal Parent(string str) { ... }
internal Parent(int i) { ... }
}
class Child : Parent {
internal Child(string str) : base(str) { ... }
internal Child(int i) : base(i) { ... }
}

Constructors don't 'inherit' the same way that methods do, but you do have the option of invoking base class constructors:
public DerivedClass(Foo foo) : base(foo)

All the other answers so far are correct. However, understand that you do not have to match the base class constructor's signature with the constructor you are defining:
public class Base
{
public Base(string theString) { ... }
}
public class Derived:Base
{
public Derived():base("defaultValue") //perfectly valid
{ ... }
public Derived(string theString)
:base(theString)
{ ... }
public Derived(string theString, Other otherInstance)
:base(theString) //also perfectly valid
{ ... }
}
... and in addition to invoking a parent class's constructor, you can also "overload" constructors within the same inheritance level, by using the this keyword:
public class FurtherDerived:Derived
{
public FurtherDerived(string theString, Other otherInstance)
:base(theString, otherInstance)
{ ... }
public FurtherDerived()
:this("defaultValue", new Other()) //invokes the above constructor
{ ... }
}

You can't inherit constructors; you have to call them explicitly (except for the default constructor, which is called, well, by default):
class A
{
public A (int i) { }
}
class B : A
{
public B (int i) : base (i) { }
}

Related

Forcing a derived class to have a constructor with a signature

How do I force all derived classes of an interface to have a constructor with a signature? This doesn't work:
public interface Constructor<T> where T : Constructor<T>, new()
{
Constructor(T);
}
public interface IParameters
{
}
public interface IRule : Constructor<IParameters>
{
//IRule (IParameters); must exist
}
You can't, not via an interface. But you can sort of get at it with an abstract class. Similar to what the accepted answer here describes, try:
public abstract class MustInitialize<T>
{
public MustInitialize(T parameters)
{
}
}
public class Rule : MustInitialize<IParameters>, IRule
{
IParameters _parameters;
public Rule(IParameters parameters)
: base (parameters)
{
_parameters= parameters;
}
}
You can't force a specific constructor signature.
Even with an abstract class as demonstrated in Mark's answer, you can only force the constructor of the abstract class, but nothing is stopping the author of the derived class to do something like this:
public class Rule : MustInitialize<IParameters>, IRule
{
public Rule()
: base (new Parameters())
{
// Assuming Parameters is a class that implements the IParameters interface
}
}
However, you can force dependency injection by using method (setter) injection:
public interface IMethodInjection<T>
{
void Method(T injected);
}
I think you can design your base class like the following example:
public abstract class MyBase
{
private MyBase()
{
}
public MyBase(string a)
{
}
}
public class MyDerived : MyBase
{
public MyDerived(string a) : base(a)
{
}
}
You can even delete the private constructor if its not needed

Call base constructor with method as argument

I am a beginner in C# and cannot find out how to call a base constructor from within a subclass:
Base class:
public class LookupScript
{
protected Func<IEnumerable> getItems;
protected LookupScript()
{
//
}
public LookupScript(Func<IEnumerable> getItems) : this()
{
Check.NotNull(getItems, "getItems");
this.getItems = getItems;
}
My derived class:
public class PresenceLookup : LookupScript
{
public PresenceLookup() :base(??)
{
//
}
List<string> myMethod()
{
return null;
}
How can I pass myMethod to the base class?
Thank you
You can't, as myMethod is an instance method, and you can't access anything to do with the instance being created within the constructor initializer. This would work though:
public class PresenceLookup : LookupScript
{
public PresenceLookup() : base(MyMethod)
{
}
private static List<string> MyMethod()
{
return null;
}
}
That uses a method group conversion to create a Func<List<string>> that will call MyMethod.
Or if you don't need the method for anything else, just use a lambda expression:
public class PresenceLookup : LookupScript
{
public PresenceLookup() : base(() => null)
{
}
}

Can I define a property which is available to both the class type and instances of the class?

I have an interface for a base class, and every class that inherits from the base class should have an identifying field which tells the application what kind of object it is.
I wanted to use this property in two different ways:
Without creating an instance of the object
if (someValue == TestA.Id)
return new TestA();
elseif (someValue == TestB.Id)
return new TestB();
And as a property of the interface
void DoSomething(ITest testObject)
{
SomeValue = testObject.Id;
}
Is there an easy way to define the Id field in the interface, but still have it available to use without creating an instance of the class?
Right now I am using the following code. I could add a read-only Id property to the interface which returns the const string, however I was hoping there was a simpler way that I'm just not aware of.
public interface ITest
{
}
public class TestA : ITest
{
public const string Id = "A";
}
In short - no.
In order to be able to do this, you'd need to be able to specify this as a instance property on the interface (and implement it in the instance), and as a static property on the type.
The compiler won't let you do this.
You can put it in the interface, and also have it as a static property. Something like:
interface IInterface { Id { get; } }
class Class : IInterface
{
public static Id { get { return 1; } }
public Id { get { return Class.Id; } }
}
I've faced a similar problem, Rachel, and I've always (unfortunately) resorted to having that factory code rely on reflection to get a "TypeID" public static property on each concrete type... thus making an additional aspect of the contractual interface, but not having it in the C# interface code.
You could do it this way.
public interface ITest
{
SomeValue Id{ get;}
}
public class TestA : ITest
{
public SomeValue Id
{
get {return TestA.StaicId; }
}
public static SomeValue StaticId
{
get {return "This is TestA";}
}
}
if (someValue == TestA.StaticId)
return new TestA();
How about using attributes? Here's a small example of what can be done:
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class IdAttribute : Attribute
{
public IdAttribute(string id)
{
this.Id = id;
}
public string Id { get; set; }
}
public interface IMyInterface
{
}
public abstract class BaseClass : IMyInterface
{
public static string GetId<T>() where T : IMyInterface
{
return ((IdAttribute)typeof(T).GetCustomAttributes(typeof(IdAttribute), true)[0]).Id;
}
}
[Id("A")]
public class ImplA : BaseClass
{
}
[Id("B")]
public class ImplB : BaseClass
{
}
internal class Program
{
private static void Main(string[] args)
{
var val1 = BaseClass.GetId<ImplA>();
var val2 = BaseClass.GetId<ImplB>();
Console.ReadKey();
}
}

Can I call constructor from another constructor (as a regular method)?

Let's say I have 2 constructors.
public class MyClass
{
public MyClass()
{
int id = 0;
//Same behaviour
}
Public MyClass(int id)
{
//Same behaviour
}
}
Both constructions implement the same behavior. The only difference is that, if the first constructor is called and the value of id = 0;
My question is to know if I can call the second constructor, instead of implemetanting the same behavior? If that's possible, do I do it?
You can do this:
public class MyClass {
public MyClass() : this(0) {
}
public MyClass(int id) {
}
}
Here's Microsoft's documentation on it. (you have to scroll down a bit; try searching for : this)
public class MyClass
{
public MyClass() : this(0)
{
}
public MyClass(int id)
{
//Same behaviour
}
}
Yes, this is called constructor chaining. It's achieved like so:
public class MyClass {
public MyClass() : this(0) { }
public MyClass(int id) {
this.id = id;
}
}
Note that you can chain to the base-class constructor like so:
public class MyClass : MyBaseClass {
public MyClass() : this(0) { }
public MyClass(int id) : base(id) { }
}
public class MyBaseClass {
public MyBaseClass(int id) {
this.id = id;
}
}
If there is a base class and you don't specify a constructor to chain to, the default is the accessible parameterless constructor, if there is one. If you do not specify a constructor to chain to and there is no accessible parameterless constructor, you will get a compile-time error.
If this is C# 4, an alternative is to use a default value for the constructor parameter (effectively making it optional):
public MyClass(int id = 0) { ...
I think this is the ideal solution for your example.
But it depends on whether you'd like to use this class as a type argument for a type parameter with a constructor constraint...
Why not put this same behavior in a private function?

C# method from derived class as delegate in base constructor

Why is the following C# not legal? Does there exist a proper workaround?
public class Base
{
public Base(Func<double> func) { }
}
public class Derived : Base
{
public Derived() : base(() => Method()) <-- compiler: Cannot access non-static method 'Method' in static context
{
}
public double Method() { return 1.0; }
}
It's effectively referring to "this" within the arguments to the base constructor, which you can't do.
If your delegate really doesn't need access to this (which your sample doesn't) you can just make it static. You could also use a method group conversion to make it simpler:
public class Base
{
public Base(Func<double> func)
{
double result = func();
}
}
public class Derived : Base
{
public Derived() : base(Method)
{
}
public static double Method() { return 1.0; }
}
If you do need to use "this", you could:
Make it a virtual method instead of calling a delegate
Make it a static method which takes an appropriate instance, e.g.
public class Base
{
public Base(Func<Base, double> func)
{
double result = func(this);
}
}
public class Derived : Base
{
public Derived() : base(x => Method(x))
{
}
private static double Method(Base b)
{
// The documentation would state that the method would only be called
// from Base using "this" as the first argument
Derived d = (Derived) b;
}
}
Basically you get the compiler error because you are referencing the instance-method Method without an instance of your class Derived. When calling base, the constructor has not yet finished and you don't have an instance of your class yet. If you made Method static it would work just fine.
Another solution to this is simply to defer the initialization of the delegate to the derived class:
public class Base {
protected Func<double> DoubleFunc { get; set; }
protected Base() {
// defer initialization by not setting DoubleFunc
// or another possibility is to set it to a dummy function:
DoubleFunc = () => 0;
}
public Base(Func<double> func) {
DoubleFunc = func;
}
}
public class Derived : Base {
public Derived() {
DoubleFunc = Method;
}
public double Method() { return 1.0; }
}
Have you tried making Method() static as the compiler indicates? The problem is that an instance of Derived isn't available until after the constructor has returned so you can't call an instance method on it.
The "workaround" would be to make Method() a static method.
I can't explain the technical reasons why this does not work but essentially you're trying to call a method on an instance which does not yet exist. How could it possibly work?

Categories