C# get access to caller in parent constructor - c#

I have a child and a parent class, as such:
class B : A{
public B : base(){
// stuff
}
}
class A{
public A(){
// how can I gain access here to the class that called me,
// ie the instance of class B that's being instantiated.
}
}
As above, my question is whether I can see who called the parent constructor within the constructor of the parent class.
One way to do this would be to have a separate function in A to which you pass this from within B. Is there anything simpler, ie can I do this during object initialization, or is that too early in the object construction process ? Does the whole object B need to be "ready" before I can access it from within A ?
Thanks!

Within A, it's easy - you just use this and cast it to B if you're confident that it really is a B rather than any other derived class. The object will already an instance of B.
However, it's generally a bad idea to call virtual methods from constructors, as the body of the B constructor hasn't been run yet, so it's only half-initialized. I've had a few situations where this is a pain, but if you tell us what you're trying to achieve we may be able to come up with something cleaner.

You can check what the type is which is being instantiated:
public A()
{
var theType = this.GetType(); // will be typeof(B) in your example
}
But acessing the instance (e.g. it's properties) is probably not wise, since the derived type is not yet initialized when the base type's constructor is executing.

Related

Why is the type of 'base' object my concrete type?

It seems a very simple question, but clearly I'm missing something.
I did a test:
class A
{
public override int GetHashCode()
{
Console.WriteLine(base.GetType().Name);
return 0;
}
}
I was expecting to find 'object' but I find 'A'.
I was relying on this behaviour to invoke the base GetHashCode is particular cases withing an implementation, calling base.GetHashCode() and I was expecting the object implementation to be invoked.
What's wrong?
base. notation changes method that is called for overridden virtual methods (like GetHashCode in your sample - base.GetHashCode() calls object.GetHashCode, this.GetHashCode() calls A.GetHashCode()). base. can also be used to hidden base class' method, but it is not the case in this sample.
Since GetType is not virtual and there is no hiding then calling this.GetType() and base.GetType() behaves identical and calls object.GetType which returns "The exact runtime type of the current instance" as specified in documentation
GetType() always returns the current type, even if called on base. To get the base type, you can do this:
class A
{
public override int GetHashCode()
{
Console.WriteLine(this.GetType().BaseType.Name);
return 0;
}
}
BTW base.GetHashCode() works as expected. If you call it within A it will execute the object implementation.
You are confusing two very different things here. One is what method implementation is called and the other is what the runtime type type of the object is.
object.GetType() is implemented in object and it will always return the runtime type of the instance it’s called upon.
Now, when you call method Foo from any given class that doesn’t implement Foo but rather inherits it from a base type (your case), base.Foo or Foo are essentially the same thing because the only existing Foo is base.Foo.
However, if the class implements it’s own Foo, bet it overriding a virtual method or hiding a non virtual method the method called will be different. Don’t get confused by the other answers stating that the behavior you are seeing is due to GetType not being virtual, that is not true.
class A { int Foo() => 1;}
class B { }
class C { new int Foo() => 2; }
Calling Foo or base.Foo from within B is the same, calling it from within C is not; the former will return 2 the latter 1.
Equalsk's comment and post (here for brevity) are what you need to know, but I'll go an extra step and tell you why you want it this way.
Given class A only inherits from System.Object,
And given class B and class C are subclasses of class A:
In class B or C, the base.GetType().Name will be A. You expected this because it's defined in the subclasses that they inherit from A.
In class A, you still get A. Why wouldn't you want object?
The answer is simple. Say I write a method like this one:
public static void DoStuff(A input)
{
}
I can send DoStuff(input) with input being classes A, B, or C. This is because their base type is A. This is desirable. We wouldn't want to implicitly (and confusingly) exclude class A from a method that takes its derivatives; if we did, we'd want A to be an uninstantiable interface.
Think of System.Object as an ancestor. If someone asks you where you came from, you don't respond "Evolution in Mesopotamia", you typically would just address the lineage relevant to your existence. The object class is essentially primordial ooze, so you won't reference it unless you're trying to tell something it should accept anything it's passed as a parameter, or are unsure what object type you'll deal with.
An example of that last case is this:
public void DoStuffAgain(object x)
{
Messagebox.Show(x.GetType().Name);
}
In theory, everything coming down the pipe would be object. Instead, you might pass this your "A" class, and you'd want to know "A" because that's what you passed it. This is true even though x is of type object.
BaseType (a property) will return your base for a class, as stated in other answers. This won't lead you to object, though, unless the class doesn't explicitly inherit from something else.

Cast Nhibernate parent entity to child

Parent
public class ParentMap : Map<Parent>
{
public ParentMap()
{
DiscriminateSubClassesOnColumn<string>("Provider").Nullable();
}
}
Children:
public class Child1Map : SubclassMap<Child1>
{
public FacebookAccountMap()
{
DiscriminatorValue("child1");
}
}
public class Child2Map : SubclassMap<Child2>
{
public FacebookAccountMap()
{
DiscriminatorValue("child2");
}
}
from service i get instance of Parent but with property item.Provider equal to childOne, how can i get instance of Child1 or Child2 based on value of proprty Provider ?
Your question I'm afraid isn't completely clear, but I'm going to take a guess:
Most likely you don't receive instances of Parent, but instances of ParentProxy, a class that NHibernate generates that inherit from Parent. This class cannot be cast to Child1, but the instance will in fact contain an instance of the Child1 class. Methods calls are forwarded to this contained class. This mechanism is part of NHibernate's lazy load system - since NHibernate needs to create the proxy object without loading the full object data, it doesn't know which exact type to use.
This scenario will happen if you get the instance by following a reference from some other class.
The idea is normally that:
You normally shouldn't need to cast. If you need to cast from base class to subclass you haven't succeeded in creating a good object oriented design and you should explore methods to avoid the cast (since the inheritance structure implies that the caller shouldn't need to care about the actual subclass, the need to cast violates this principle and should therefore be avoided when possible).
If you really must access the true Child1 instance, you could provide an As<T>() method in the base class.

Overloading using dynamic and inheritance

I'm having an issue where I need dynamic dispatch (or at least that's what I think it should be called) with an inheritance structure. More specifically, I would like to use dynamic dispatch so I can add more specific overloads in inherited classes. I haven't been able to find anyone with quite the same problem as mine (things I find always talk about overrides in inherited classes, I need dynamic overloading). The strongly simplified situation is as follows:
class A
{
private void DoSpecificStuff(object a);
private void DoSpecificStuff(SomeClass a);
}
class B<T> : A
{
private void DoSpecificStuff(OtherClass<T> a);
}
Then inside A, I have some function that consumes fields of some class using reflection. It goes like this:
public void Consume(JetAnotherClass a)
{
// Fetch all fieldinfo's from a and for each fieldinfo, do this:
foreach(FieldInfo info in a's fieldinfo's...)
DoSpecificStuff((dynamic)fieldInfo.GetValue(a))
}
The calling site works as follows:
B b = new B();
b.Consume(new JetAnotherClass());
Now, every time the fieldInfo.GetValue(a) finds an instance of SomeClass, the desired overloaded function is being called with SomeClass as formal parameter. But when an instance of OtherClass<>T> is returned, it is DoSpecificStuff(object a) that gets called instead of DoSpecificStuff(OtherClass<>T> a).
Why does my dynamic dispatch work perfectly within one class, but breaks when another class offers more overloads that should be dynamically dispatched on? Doesn't the dynamic dispatch start by looking inside the top-most instance, which is of type B?
PS: replacing private by (virtual) protected or anything like that doesn't help. In fact, it's way weirder that using private does work for the overloads inside A, since we're calling DoSpecificStuff with an implicit this parameter of type B.
I think that you are confusing to separate mechanisms:
Polymorphism - or the ability to runtime call a function in a sub class, even though the reference is of base class type.
Overload resolution that (normally, without dynamic) is a compile time resolution of the most specific matching function.
When you are using dynamic to defer the overload resolution to runtime you are still doing an overload resolution. The Consume method is in A so it will only look in A and have no idea of that B even exists.
To get the behaviour you want, I think that you should make a separate virtual method for calling DoSpecificStuff that contains the dynamic magic. Then repeat that functionality in class B. That way an instance of B will use the method in B and find the right candidates when doing the overload resolution.

Why would I want to instantiate an object in a base class variable?

BaseClass obj = new SubClass(); // Subclass : BaseClass
What does that mean in OOP? When would I want to do that instead of just creating a SubClass object? If someone can give me a real life example I would really apreciate it.
obs: I understand there's some side effects regarding virtual methods and stuff, but what I'm really confused here is about the concept and uses of this.
The most common reason that I can think of would be in a scope where multiple types of subclass may be assigned to that variable:
Vehicle myWheels;
if (iHaveALicense) {
myWheels = new Car();
} else {
myWheels = new Bus();
}
A very simple example is to think about a factory class. If one class takes a dependency on some Factory<T>, you can inject the "concrete" version, using inheritance. The consuming class doesn't care about how the concrete version works, just that it implements some contract.
"What does that mean in OOP?" - In C#, it means that SubClass inherits everything about BaseClass and has access to everything inside of BaseClass, minus private members. By doing this, anywhere a BaseClass is required, a SubClass may be used in its place. In my example, you might define what a factory should do by exposing an abstract base class. The inheriting class is then free to implement the behavior without any consumers caring about how the work is being done.
(This is only one example--inheritance, when not abused, is a very powerful tool.)
Assume you have another class which inherits BaseClass:
public class NewSubClass : BaseClass
When you initialize your object the way you shown, you can do that:
BaseClass obj = new SubClass();
obj = new NewSubClass();
on the other hand something like that:
SubClass obj = new SubClass();
obj = new NewSubClass();
wouldn't compile at all.
That would be called polymorphism.
suppose there is a function that takes baseclass as argument.
void my_function(Animal ani)
{
Console.WriteLine(ani.makeSound());
}
Now if you make virtual method in the base class and override them in the derived class and then pass any object derived from animal to the function. Then makeSound would make generate sound according to the derived object that you have passed.
That way you don't have to make this function for everytype of animal that produces sound.

Easy conversion from instance of inherited class

I have two classes, one which inherits the other, for example:-
public class A
{
public string AA { get; set; }
public double AB { get; set; }
}
and
public class B : A
{
public double? BA { get; set; }
}
Now, I know that if I have an instance of object B, I can cast that as type A, but I have an instance of A that I want to instantiate as a type B object. I know I could put a constructor in B's class which copies all the property values over, but the base class, A, has quite a few properties and may well have more added, so I'm worried about missing one or forgetting to add it in to B's constructor when I add it to A. Is there an easy way of doing this, please?
-------Edit------
Thanks folks, not my use-case unfortunately, it's a question a mate's fired at me. As far as I'm aware there are issues and he can't change the base class. As I understand it, the base class is one that hooks into a database call, he then wants to grab that data and add some extra properties for an admin editing screen which his code will then use to update the base data object's properties. My first reaction was to have the base object as a property of his object, but there's a reason it's significantly easier for him to have it "flattened" with the tools he's using. I didn't think there was a way of doing this, but I thought I'd check in case I was missing something - I thought it would be easier to just ask the basic question, rather than include the background, which would probably just raise more questions and muddy the water (AFAIK he's suffering from "circumstances beyond his control", with this).
I know I could put a constructor in B's class which copies all the property values over, but the base class, A, has quite a few properties and may well have more added, so I'm worried about missing one or forgetting to add it in to B's constructor when I add it to A. Is there an easy way of doing this, please?
Typically, this is a sign of a design flaw. I would rethink your design first, and determine whether this is truly necessary, or if there is another approach you can use here. That being said...
There is no easy way to do this. If you need a B instance to be created from your A instance, you'll really need to copy the values over to the new instance.
A better option, however, would potentially be to add a (potentially protected) constructor to A that sets all of these properties, given another A instance. B could then use this to create itself, which at least keeps the requirements for matching all of the properties within the class that defines them. This should make it easier to maintain this over time.
I agree with the other remarks, you're better off using a different design, such as composition instead of inheritance.
Composition, shown below, allows you to modify class A without requiring any changes to class B.
public class B
{
// Constructor
public B(A A) { this.A = A; }
// Class A as a read-only property
public A A { get; private set; }
// Other properties of class B
public double? BA { get; set; }
}
Reverse Polymorphism is not supported in c#.
As Reed Copsey said, this is typically a sign of a design flaw. I would re-work the class diagram if you need something like this to work. It sounds like some sort of mistake was made in the inheritance architecture somewhere.
If all you need is for both child and parent to implement common methods so that when either of the objects is passed to some function it can operate on some common methods on the passed-in object, then just have the two of them implement the same interface (polymorphism), or type the function parameter as the base class and make sure the methods exist on the base class.

Categories