I have a generic abstract base class from which I would like to derive from a dynamic type built through reflection.emit. Also I need to customize the derived class default constructor to initialize some fields. To build the default constructor of the derived class correctly I need to obtain the default constructor of the base class and invoke it. The problem is that I'm not being able to get the default constructor from the base class.
An example:
public abstract class Test<T>
{
private T data;
public abstract void Go();
}
public class TestDerive : Test<int>
{
public override void Go()
{
}
}
class Program
{
static void Main(string[] args)
{
ConstructorInfo[] constructors = typeof(Test<>).GetConstructors();
int length = constructors.Length;
}
}
I've tried everything and length is always zero. I don't understand. I've inspected similar cases in the reflector and there's indeed a call to the base constructor of the abstract class. The question is how do I get it to do the same ?
The default constructor of an abstract class is protected - you need to specify binding flags to access it via reflection. You can use
typeof(Test<>).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)
(It makes no practical difference whether it's public or protected in normal code, of course, as you can't call the constructor other than from a derived type.)
Note that this is the case whether or not the class is generic - it's the abstractness that's causing you problems.
Related
I'm looking for the best way to provide a method in an (abstract) base class, which all inheriting classes should be able to use.
This method needs to reference fields and properties of the inheriting types.
Is there a way to provide such a prototype method which doesn't require me to either:
Pass a reference to each inheriting instance in question
Implement a method on each inheriting class which passes a reference to itself to the base class's method
Write an extension method for implementing classes
All of the above work, but seem somewhat inconvenient and unelegant in their own way.
Here is an example where I implemented the three above methods of referencing the inheriting class:
using System;
namespace Test
{
public abstract class BaseClass
{
public void ReferenceInheriting(object InheritingInstance)
{
Console.WriteLine("Do things specific to the inheriting class or instance thereof: " + InheritingInstance.GetType().Name);
}
}
public class Inheriting : BaseClass
{
public void MakeUseOfBaseClassImplementation()
{
base.ReferenceInheriting(this);
}
}
public static class Extensions
{
public static void BeAvailableForAllImplementing(this BaseClass Inh)
{
Console.WriteLine("Do things specific to the inheriting class or instance thereof: " + Inh.GetType().Name);
}
}
class program
{
public static void Main(string[] args)
{
Inheriting inh = new Inheriting();
Console.WriteLine("Method 1: Calling the inherited method from an inheriting instance, passing a reference to the instance:");
inh.ReferenceInheriting(inh);
Console.WriteLine("Method 2: Implementing call to the base class's method in own class:");
inh.MakeUseOfBaseClassImplementation();
Console.WriteLine("Method 3: Extension method for all implementing classes:");
inh.BeAvailableForAllImplementing();
}
}
}
The three approaches all produce the same output, but have drawbacks.
Short of parsing caller information, is there another way to do this?
It's not a big deal of course, but I'm interested in making this method as user friendly as possible, both for implementing inheritance and for calling.
Thank you!
You don't need any of that.
This:
public void reflectInheriting(object inheritingInstance)
{
Console.WriteLine("Do things specific to the inheriting class or instance thereof: " + inheritingInstance.GetType().Name);
FieldInfo fi = inheritingInstance.GetType().GetField("getMe");
Console.WriteLine(fi.GetValue(inheritingInstance));
}
Can be rewritten as simply:
public void reflectInheriting()
{
Console.WriteLine("Do things specific to the inheriting class or instance thereof: " + this.GetType().Name);
FieldInfo fi = this.GetType().GetField("getMe");
Console.WriteLine(fi.GetValue(this));
}
And that's all you need.
C# saves the actual underlying type of an object regardless of how it's cast, so even inside BaseClass, this.GetType() will be Inheriting.
Program output to prove nothing has changed:
Method 1: Calling the inherited method from an inheriting instance, passing a reference to the instance:
Do things specific to the inheriting class or instance thereof: Inheriting
Use me in BaseClass
Method 2: Implementing call to the base class's method in own class:
Do things specific to the inheriting class or instance thereof:
Inheriting
Use me in BaseClass
Method 3: Extension method for all implementing classes:
Do things specific to the inheriting class or instance thereof: Inheriting
Use me in BaseClass
You could use Reflection, but that is kind of a weapon of last resort. The idiomatic way to access a property or method in a descendent class is to make it abstract in the base class.
public abstract class BaseClass
{
public void GetInheriting()
{
Console.WriteLine("GetMe is: {0}", this.GetMe);
}
protected abstract string GetMe { get; }
}
public class Inheriting : BaseClass
{
protected override string GetMe => "Use me in BaseClass";
public void MakeUseOfBaseClassImplementation()
{
base.GetInheriting();
}
}
public class Program
{
static public void Main()
{
var o = new Inheriting();
o.MakeUseOfBaseClassImplementation();
}
}
Link to Fiddle
Output:
GetMe is: Use me in BaseClass
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) { }
}
I'm trying to determine the value of an attribute on a derived class, when it's been passed into a method through a base class parameter.
For example, complete code sample below:
class Program
{
static void Main(string[] args)
{
DerivedClass DC = new DerivedClass();
ProcessMessage(DC);
}
private static void ProcessMessage(BaseClass baseClass)
{
Console.WriteLine(GetTargetSystemFromAttribute(baseClass));
Console.ReadLine();
}
private static string GetTargetSystemFromAttribute<T>(T msg)
{
TargetSystemAttribute TSAttribute = (TargetSystemAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(TargetSystemAttribute));
if (TSAttribute == null)
throw new Exception(string.Format("Message type {0} has no TargetSystem attribute and/or the TargetSystemType property was not set.", typeof(T).ToString()));
return TSAttribute.TargetSystemType;
}
}
public class BaseClass
{}
[TargetSystem(TargetSystemType="OPSYS")]
public class DerivedClass : BaseClass
{}
[AttributeUsage(AttributeTargets.Class)]
public sealed class TargetSystemAttribute : Attribute
{
public string TargetSystemType { get; set; }
}
So, in the above example, I had intended that the generic GetTargetSystemFromAttribute method returns "OPSYS".
But, because the DerivedClass instance has been passed to ProcessMessage as the base class, Attribute.GetAttribute is not finding anything because it's treating the DerivedClass as the Base Class, which does not have the attribute or the value I'm interested in.
In the real-world there are dozens of Derived Classes, so I was hoping to avoid lots of:
if (baseClass is DerivedClass)
...which is suggested as the answer in the question How to access the properties of an instance of a derived class which is passed as a parameter in the form of the base class (which relates to a similar issue, but with properties). I was hoping because I'm interested in Attributes there's a nicer way of doing it, especially as I have dozens of derived classes.
So, here's the question. Is there any way I can obtain the TargetSystemType value of the TargetSystem Attribute on my derived classes in a low-maintenance way?
You should change this line:
(TargetSystemAttribute)Attribute.GetCustomAttribute(typeof(T), typeof(TargetSystemAttribute));
with this:
msg.GetType().GetCustomAttributes(typeof(TargetSystemAttribute), true)[0] as TargetSystemAttribute;
P.S. GetCustomAttributes returns array and I picked up first element for example where only 1 attribute is expected, you may need to change, but the logic is the same.
In c# we can't create an obeject of a abstact class or interface it means abstract class do not have any constructor, is it true ?
or if it have then what is it's purpose there?
As others have said, abstract classes usually have constructors (either explicitly or the default one created by the compiler) - and any derived class constructor will have to chain through the abstract class's constructor in the normal way. That's the important bit... suppose you have an abstract class which stores the name associated with an instance - because you always want a name, and you don't want to write the Name property in each concrete derived class. You might provide a constructor which takes that name and assigns it to a field... and then every subclass constructor would have to go through that constructor, so that you still knew you'd always have a name. If you want to know more about constructor chaining, read my article on it.
Here's an example of that:
public abstract class DemoBase
{
private readonly string name;
public string Name { get { return name; } }
protected DemoBase(string name)
{
this.name = name;
}
// Abstract members here, probably
}
public class FixedNameDemo : DemoBase
{
public FixedNameDemo()
: base ("Always the same name")
{
}
// Other stuff here
}
public class VariableNameDemo : DemoBase
{
public VariableNameDemo(string name)
: base(name)
{
}
// Other stuff here
}
To further answer your comment on BoltClock's answer, asbtract classes can't have private abstract methods, but they can have private constructors. Indeed, it's sometimes useful to have only private constructors in an abstract class, because it means the class can only be derived from within the program text of the same class. This allows you to create pseudo-enums:
public abstract class ArithmeticOperator
{
public static readonly ArithmeticOperator Plus = new PlusOperator();
public static readonly ArithmeticOperator Minus = new MinusOperator();
public abstract int Apply(int x, int y);
private ArithmeticOperator() {}
private class PlusOperator : ArithmeticOperator
{
public override int Apply(int x, int y)
{
return x + y;
}
}
private class MinusOperator : ArithmeticOperator
{
public override int Apply(int x, int y)
{
return x - y;
}
}
}
In this respect, an abstract private method/property could make sense - it could be accessed by the base class but provided by the derived classes within the same class's program text. However, it's prohibited by the specification. Usually, protected abstract members would solve the same problem - but not quite always.
Good question. Here's why Abstract classes need constructors even though they cannot be instantited.
In any Object oriented language like C#, object construction is an hierarchical process. Look at the code below. When you instantiate any object of type DerivedClass, it must construct the base object first before creating the object of typeof DerivedClass. Here the base class may or may not be an Abstract class. But even when you instantiate an object of a concrete type derived from an abstract class it will still need to call the constructor of the Base class before the object of DerivedClass type is created, hence you always need a constructor for Abstract class. If you have not added any constructor, C# compiler will automatically add a public parameterless constructor to the class in the generated MSIL.
public class BaseClass
{
public BaseClass()
{
Console.WriteLine("BaseClass constructor called..");
}
}
public class DerivedClass : BaseClass
{
public DerivedClass()
{
Console.WriteLine("DerivedClass constructor called..");
}
}
DerivedClass obj = new DerivedClass();
//Output
//BaseClass constructor called..
//DerivedClass constructor called..
PS: Assuming, If Abstract base classes
are not allowed to have constructors
because they need not be instantiated,
the whole fundamentals of the object
oriented programming will go on toss.
The idea behind Abstract types are to
represent objects that have some
features and behaviours but not
complete as whole to allow independant
existence.
No. it means that operator new is not allowed to create object from this type of class.
The purpose might be that are allocated/initialized some properties of class.
abstract usually leave some methods to implement.
Regarding the interface, this structure holds only the signatures of method, delegates or events. That may be implemented in class that use interface. You cant create a object.
Read about new
EDIT:
What is the purpose of constructor in abstract class ?
When one class inherit another class, the parent class of it had to be created first while object is crated. In class do not implement some special constructor always is used default one [className()]. When you override some method then the implementation of functionality is taken form class which override the method. This is why method used in constructor should never be virtual. Same logic for abstract class, such class can have a lot of functionality, and only one method that should be implemented by child class.
Abstract classes have constructors but you can't call them directly as you can't directly instantiate abstract classes.
To answer your comment, the concept of a private abstract method or property makes no sense, because private prevents anybody else from accessing it, and abstract prevents itself from accessing it. So there would essentially be no possible way to call it.
EDIT: see Jon Skeet's answer on private constructors. Private members of other kinds cannot exist in abstract classes, though.
Abstract classes do have constructors. When you create an instance of a derived class, its parent class' constructors are called. This applies to classes derived from abstract classes as well.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why can’t I create an abstract constructor on an abstract C# class?
Why I can't declare abstract an constructor of my class like this:
public abstract class MyClass {
public abstract MyClass(int param);
}
Constructors are only applicable to the class in which they are defined, that is, they are not inherited. Base class constructors are used (you have to call one of them, even if only calling the default one automatically) but not overridden by deriving classes. You can define a constructor on an abstract base class -- it can't be used directly, but can be invoked by deriving classes. What you can't do is force a derived class to implement a specific constructor signature.
It is perfectly reasonable to have a constructor defined, typically as protected, in order to define some common set up code for all derived classes. This is especially true, perhaps, when the abstract class provides some other default behavior which relies on this set up. For example:
public abstract class Foo
{
public string Name { get; private set; }
protected Foo( string name )
{
this.Name = name;
}
}
public class Bar : Foo
{
public Bar() : base("bar")
{
...
}
}
You can't declare it abstract, but you can have a constructor on your abstract class; just remove the word abstract and provide a body for it.
Constructors are closer to static methods rather than "regular" methods. Like static methods, they can be overloaded, but not overriden. That is, they are not inherited but can be redefined.
public BaseClass
{
public BaseClass( String s ) { ... }
public static void doIt ( String s ) { ... }
}
public SubClass extends BaseClass
{
public SubClass( String s ) { ... }
public static void doIt ( String s ) { ... }
}
public SubClass2 extends BaseClass
{
}
new SubClass( "hello" );
SubClass.doIt( "hello" );
new SubClass2( "hello" ); // NOK
SubClass2.doIt( "hello" ); // NOK
Constructors and static methods are never dispatched dynamically (virtually) -- You always know the concrete type you instantiate or the concrete class of the static method. That's why it makes no sense to have abstract constructor and abstract static method. That's why you can also not specify constructor and static method in interfaces.
You can even think of constructor as static factory method (and see the corresponding pattern):
MyClass obj = new MyClass(); // the way it is
MyClass obj = MyClass.new(); // think of it like this
The only case I see where it would make sense to define abstract constructor or abstract static method would be if reflection is used. In this case, you could ensure that all subclass would redefine the corresponding static method or constructor. But reflection is another topic...
Note: in languages such as Smalltalk where classes are regular objects, you can override static method and have abstract constructor. But it doesn't apply to Java because classes are not "regular" objects even if you can get them with reflection.
Abstract implies virtual. A non-default constructor can never be called polymorphically, so virtual and abstract are not allowed on constructors.
IF in a future version of C#, generics are enhanced to allow calling non-default constructors through a generic type parameter, then polymorphic calls to constructors would be possible and virtual and abstract constructors might be added as well.
What wrong with this:
public abstract class MyClass {
protected MyClass(int param)
{
}
}
In this case you oblige all derived classes to call base class constructor.
Because abstract constructors are not supported.
But a abstract class can have a constructor.
A constructor is not an ordinary method. It has a special purpose, and so is restricted to language features that make sense for that purpose. See also: Why do constructors not return values?
By definition, the class can't be instantiated directly, so in a sense, it already is abstract.