call constructor with instanciated superclass in c# - c#

I have this construct.
public class SuperClass{}
public class InheritedClass : SuperClass{}
I want my instantiated Superclass to become an InheritedClass instance.
var superClassInstance = new SuperClass();
InheritedClass inHeritInstance = new InheritedClass(superClassInstance) ;
Somebody told me, that will not work without setting all properties in the Constructor.
Is that correct?

I want my instantiated Superclass to become an InheritedClass instance.
This is not possible. If you want it to be an instance of InheritedClass you must create one. You cannot upcast an instance of SuperClass.

That's true.. you can not Assign directly, In Constructor you have to transfer.
Instead..
you should create interface and implement the Interface into the class from where you are passing the value.
Now in into InheritedClass create constructor with the the interface as parameter, so whatever values are assigned into the First class, will be passed into InheritedClass
here you will have full access of First Class property.
Refer below dotnetfiddle url.
http://dotnetfiddle.net/8AgOCF

Yes, that is correct. There is no inbuilt way to provide your own baseclass object to promote to subclass. Each subclass will build it's own baseclass before it calls the subclasses' constructor on it.
You will need to write your own constructor in the subclass that copies all relevant data.

In a sense, yes, I'm afraid that is correct. A constructor is, by definition, creating a new instance. So anything from an existing instance is going to have to be copied to the new instance. It might be something like this:
public InheritedClass(SuperClass superClassInstance)
{
// base fields
Field1 = superClassInstance.Field1;
Field2 = superClassInstance.Field2;
Field3 = superClassInstance.Field3;
// local fields
Field4 = "some value";
// etc.
}
Or you can split the work between the classes, something like this:
public SuperClass(superClassInstance)
{
Field1 = superClassInstance.Field1;
Field2 = superClassInstance.Field2;
Field3 = superClassInstance.Field3;
}
then in the derived class:
public InheritedClass(superClassInstance)
: base(superClassInstance)
{
Field4 = "some value";
// etc.
}
It gets a lot easier the other way around, creating a SuperClass from InheritedClass, since any instance of InheritedClass is an instance of SuperClass and can polymorphically be interpreted as such:
SuperClass someObject = inheritedClassInstance as SuperClass;
(Note that this would not be a "new instance" so watch out for reference errors.) You might be able to do the same in reverse:
InheritedClass someObject = superClassInstance as InheritedClass;
But there is no guarantee that superClassInstance is also an instance of InheritedClass so you'd want to check for errors here. And, again, this is not a new instance.
Using composition instead of inheritance you can potentially achieve your goal with less code. For example, if you have a class like this:
public class InheritedClass
{
public SuperClass BaseObject { get; private set; }
// other fields
}
Then you can include a constructor in InheritedClass which just sets that one object:
public InheritedClass(SuperClass superClassInstance)
{
BaseObject = superClassInstance;
}
Again, however, note that this is not a new instance of SuperClass in the property but a reference to the existing one. To ensure a new one you'd still have to write your manual code (possibly in a .Copy() or .Clone() method on SuperClass?) to duplicate the instance.
In short, after all of my directionless brainstorming, cloning an instance field-by-field is going to require putting that field-by-field code somewhere.

Ok, here (a and b fields are for demo purposes):
public class SuperClass
{
object a;
public SuperClass()
{
a = "123";
}
// you need to have this
public SuperClass(SuperClass copy)
{
a = copy.a;
}
}
public class InheritedClass : SuperClass
{
object b;
public InheritedClass()
{
Init();
}
// and this
public InheritedClass(SuperClass super): base(super)
{
// bacause you can't call base() and this()
Init();
}
private void Init()
{
b = "456";
}
}
So you can do
var super = new SuperClass();
var inherited = new InheritedClass(super);
Proof.

I found a solution, which can at least copy all the properties automatically.
public InheritedClass(SuperClass superClassInstance)
{
foreach(var currentItem in superClassInstance.GetType().GetProperties())
{
GetType().GetProperty(currentItem.Name).SetValue(this,currentItem.GetValue(superClassInstance,null),null);
}
}

Related

Base class object as argument for derived class

(Simplified) Scenario:
public class BaseClass
{
public int BaseClassInt {get; set;}
public BaseClass(int pBaseClassInt)
{ this.BaseClassInt = pBaseClassInt; }
}
public class DerivedClass : BaseClass
{
public int DerivedClassInt {get; set;}
public DerivedClass (int pBaseClassInt, int pDerivedClassInt) : base(pBaseClassInt)
{ this.DerivedClassInt = pDerivedClassInt; }
}
If I want to instantiate a DerivedClass-object I have to pass all arguments required to create a BaseClass-object and a DerivedClass-object. Also for every BaseClass-constructor I have to (at least should in my concrete case) provide a constructor with the same arguments in the derived class, plus arguments for the derived class properties. Then, if I change or delete a constructor in the base class I have to change or delete the corresponding contructor in the derived class(es).
I wonder if it is possible to use a constructor for the derived class which accepts a base class-object as an argument:
public DerivedClass(BaseClass pBaseClassObejct, int pDerivedClassInt)
{
// to make clear what I intend to do - looks silly of course
this = (DerivedClass)pBaseClassObject;
this.DerivedClassInt = pDerivedClassInt;
}
This could be called:
DerivedClass DerivedClassObject = new DerivedClass((new BaseClass(1),2);
If constructors in the base class would change, I wouldn´t have to mind it for the derived class. Is there any way to achieve this?
Think about this line for a moment:
this = (DerivedClass) pBaseClassObject;
Let's ignore the fact that you cant set this directly that way, and focus on the rest.
Imagine Giraffe and Elephant are both implementations of AfricanAnimal:
// By extension, ellie is also an AfricanAnimal
Elephant ellie = new Elephant();
// assume ellie is passed in as a param here (she can
// be, because she is an AfricanAnimal after all!):
public Giraffe(AfricanAnimal ellie)
{
this = (Giraffe) ellie; // Can't do this!
}
You can't (and would not want to) force ellie into being a giraffe, because a giraffe may have properties etc. that ellie lacks, and ellie may have properties that Giraffes don't have. Yet, using an AfricanAnimal as your parameter type there, would allow for just that.
Note: You could write that code and pass a Giraffe in, and all would be fine, but then again, that makes little sense; then you might as well use the Giraffe type as the parameter.
If you replace this with an instance variable, you would be able to compile with something like the following...
public Giraffe(AfricanAnimal ellie)
{
this.varOfTypeGiraffe = (Giraffe) ellie;
}
... but as soon as you run it with an Elephant as a a prameter, you will get an exception similar to:
InvalidCastException: Unable to cast object of type 'Elephant' to type 'Giraffe'.
TL;DR: This is a bad idea. Don't even try.
You cannot make a base constructor run from inside the body of any derived method (including the derived constructor). Even if you could, a base instance would not have retained any information about which constructor was used to instantiate it so there would be no way to know which base constructor should be called.
The above refers to the general case where a base constructor can potentially modify application state not directly related to the base class (e.g. by changing the value of static fields somewhere). You could use reflection to copy property values from a base instance to the derived instance being created, but this is practically unworkable because
It requires that you create a base instance in the first place -- what if the base is abstract, or if creating one has side effects?
You need a guarantee that the base constructor does not modify application state. But the aim here is to be independent of what the base constructors do, so you are back to square one.
No, that is not possible and should not be, because it doesn't make sense.
If it was possible and you deleted/changed the base class constructor, you would still need to change the code which creates the base class object that you would use as an argument to the derived class constructor.
Also, not all base classes are concrete. You would not be able to create an abstract base class, right?
This feature is not available. I think what you want is a little like this:
Suppose C# had a keyword allbaseargs and allowed code like this:
public class DerivedClass : BaseClass
{
public int DerivedClassInt { get; set; }
public DerivedClass (allbaseargs, int pDerivedClassInt)
: base(allbaseargs)
{
DerivedClassInt = pDerivedClassInt;
}
}
Then this could only work if BaseClass had only one (accessible) instance constructor.
The compiler should then examine the sole base constructor and substitute the magical word allbaseargs with the parameters of that constructor.
However, C# does not have this feature, and you would have to hand-code everything, which includes changeing all : base(...) calls of all derived classes when the constructor signature changes.
It is allowed to have the signature:
public DerivedClass(BaseClass pBaseClassObejct, int DerivedClassInt)
like you suggest, but you would not be able to chain the : base(...) easily. You would have to equip BaseClass with a construtor that took another instance in and copied all "state" (all instance properties and fields and such) from that other instance to "this". I do not recommend that solution.
This might be help!
Solution A: Create Inherit instead of base!
public static class Test
{
public static T Foo<T>(string text, int num) where T : BaseClass
{
T #base = (T)Activator.CreateInstance(typeof(T), new object[] { text, num });
//...
return #base;
}
public static void Main()
{
InheritClass inherit = Foo<InheritClass>("Hi there", 10);
}
}
Solution B: Copy base to inherit
public static class Test
{
public static TInherit As<TBase, TInherit>(this TBase #this) where TInherit : TBase
{
var type = typeof(TInherit);
var instance = Activator.CreateInstance(type);
foreach (var property in type.GetProperties())
if (property.CanWrite)
property.SetValue(instance, property.GetValue(#this, null), null);
return (TInherit)instance;
}
public static BaseClass Foo(string text, int num)
{
BaseClass #base = new BaseClass(text, num);
//...
return #base;
}
public static void Main()
{
InheritClass inherit = Foo("Hi there", 10).As<BaseClass, InheritClass>();
}
}
Notes: you can have simple 'As()' found here, but i prefer mine (where Inherit : TBase), where it's more safe and support converting base to inherit of inherit class.

this or base? In which case could we use base instead of this?

In the following code
// MVVM Views part class
public partial class DashBoard : UserControl
{
public DashBoard()
{
InitializeComponent();
this.DataContext = new DashBoardViewModel();
}
}
Could we use base.DataContext instead this.DataContext. In which case could we use base instead of this?
It's usually clearer to use this. You normally only specify base when you want to explicitly call a base class constructor or the base implementation of an overridden method or property.
Using base.DataContext would work, but it would might imply that this.DataContext would mean something different.
You use this to access a method defined in the present class (or superclass if it's not in the present class). You use base to access a method in the superclass or higher. In this case you could have used either (or none as Marc points out above).
I prefer to emit this except when it's (rarely) required.
To add to what the others have said, base. is used when you've overridden something from the base class with either the overrides or new keywords, you'll need to use base to gain access to the original method.
class a
{
public virtual void method1()
{
}
public string property1 { get; set; }
}
class b : a
{
// this has it's own instance in b, the only way to get to
// the original property1 is with base (or reflection)
public new string property1 { get; set; }
public override void method1()
{
// the only way to get to the original method1 and property1
base.method1();
base.property1 = "string";
}
}
In your example if the DataContext property uses either of these keywords then base and this don't mean the same thing at all.
Considering your case u are trying to initialize DataContext property of class DashBoard with some value. So if you then call DataContext typed property of (base)UserControl class object, it still will be not initialized. Therefore, to decide which property to initialize, u must to look to your program's logic.
Basicly MSDN tells that u should use (base.) in two scenarious:
-Call a method on the base class that has been overridden by another method.
-Specify which base-class constructor should be called when creating instances of the derived class.
In my practise i used first scenario when (this) method ends with exception, i was trying to call more general (base) method. Good luck!

Creating a cloned copy of subclass from baseclass

Consider this scenario:
public class Base
{
public int i;
}
public class Sub : Base
{
public void foo() { /* do stuff */}
}
And then I want to, given an instance of Base get an cloned instance of Sub (with i=17 in this case) so that I can call foo in the subclass.
Base b = new Base { i=17 };
Sub s = CloneAndUpcast(b);
s.foo();
However, how can I create CloneAndUpcast?
I am thinking that is should be possible to recursively clone all of Base-members and properties using reflection. But quite some work.
Anyone with better, neater ideas?
PS. The scenario where I am thinking about using this is a set of "simple" classes in a tree-like structure (no cyclic graphs or similar here) and all the classes are simple value holders. The plan is to have a stupid layer holding all values and then an similar set of classes (the subclasses) that actually contains some business-logic the value-holders shouldn't be aware of. Generally bad practice yes. I think it works in this case.
You could use AutoMapper to avoid the tedium of writing the copy constructors.
public class MyClass : MyBase
{
public MyClass(MyBase source)
{
Mapper.Map(source, this);
}
}
and you need to run this once when your application starts up
Mapper.CreateMap<MyBase, MyClass>();
You can download AutoMapper from https://github.com/AutoMapper/AutoMapper
Here's one way (out of many possibilities) that you could do something like you're asking. I'm not sure this is very pretty and can be kind of ugly to debug, but I think it works:
class BaseClass
{
public int i { get; set; }
public BaseClass Clone(BaseClass b)
{
BaseClass clone = new BaseClass();
clone.i = b.i;
return clone;
}
}
class SubClass : BaseClass
{
public int j { get; set; }
public void foo() { Console.WriteLine("in SubClass with value of i = {0}", i.ToString()); }
}
class Program
{
static void Main(string[] args)
{
BaseClass b1 = new BaseClass() { i = 17 };
BaseClass b2 = new BaseClass() { i = 35 };
SubClass sub1 = CloneAndUpcast<SubClass>(b1);
SubClass sub2 = CloneAndUpcast<SubClass>(b2);
sub1.foo();
sub2.foo();
}
static T CloneAndUpcast<T>(BaseClass b) where T : BaseClass, new()
{
T clone = new T();
var members = b.GetType().GetMembers(BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < members.Length; i++)
{
if (members[i].MemberType== MemberTypes.Property)
{
clone
.GetType()
.GetProperty(members[i].Name)
.SetValue(clone, b.GetType().GetProperty(members[i].Name).GetValue(b, null), null);
}
}
return clone;
}
}
Basically, as you suggested, you use reflection to iterate through the object's properties (I set i and j as public properties) and set the values accordingly in the cloned object. The key is using generics to tell CloneAndUpcast what type you're dealing with. Once you do that, it's pretty straightforward.
Hope this helps. Good luck!
Per the "Gang of Four" : "Favor composition over inheritance" and this is a perfect reason to do so...
If we have a SuperClass that looks like this:
public class SuperClass : Person
The SuperClass can easily decorate the Person class adding properties not found in Person class.
But what happens if the Superclass decorations are only for the GUI? For example a bool value indicating "Selected". We are still able to get all Persons from the DB in a List but we run into trouble trying to create the Superclass and merge the DB results.
foreach( var person in myPersonList){
var sc = new SuperClass();
sc.Selected = false;
sc=person;
}
The compiler complains because Superclass is not a Person to the compiler it's a Superclass. The only way to fill in the properties of the Person subclass is to iterate and set each one... like this.
SuperClass.Name = Person.Name;
SuperClass.Id = Person.ID;
Pretty tedious indeed. But there's a better way.... Don't make Superclass inherit from Person
public class SuperClass{
public Person ThisPerson {get;set;}
public bool Selected {get;set;}
}
This gives us "Containment" The Superclass now contains a Person class.
Now we can do this:
foreach(var person in MyPersonList){
var sc = new Superclass();
sc.Selected = false;
sc.Person = person;
}
The consumer of this class must now qualify the properties of the Superclass/Person like this...
forach(var sc in MySuperClassList){
var selected = sc.Selected;
var name = sc.Person.Name;
}
The beauty of this is that in the future, you can add any other container you want and it will NOT affect any other containers. You can also morph the Superclass to anything it contains. If each of the contained classes become Interfaces, then that's one step futher down the road.
Well, since b isn't a Sub, we can't "clone" it as one.
If Base has an appropriate combination of constructor and public properties to let a constructor in Sub ensure that its base would therefore have the same state as b, then we could use that.
I think I'd by-pass the whole thing though. If all we care about is that s have the same state in its base as b, and it has not other state that we're going to care about (or else we'd have to be passing it through to the CloneAndUpcast method), then do we need s at all?
A static method could take a Base and we could just use static public void foo(Base bc). We could even define it as an extension method static public void foo(this Base bc) and then code the call as b.foo(). The only thing this won't let us do that CloneAndUpcast() lets us do is access protected members.
Clone is a bad practice and your question is the reason for that (subclass cloning).
In general, you should just use copy cotrs instead and have the subclass accept a parent as a parameter.
public Base(){}
public Base(Base pSource){}
public Sub(){}
public Sub(Base pSource, other parameters...){}
public Sub(Sub pSource){}

Methods for Lazy Initialization with properties

I'm currently altering a widely used class to move as much of the expensive initialization from the class constructor into Lazy Initialized properties. Below is an example (in c#):
Before:
public class ClassA
{
public readonly ClassB B;
public void ClassA()
{
B = new ClassB();
}
}
After:
public class ClassA
{
private ClassB _b;
public ClassB B
{
get
{
if (_b == null)
{
_b = new ClassB();
}
return _b;
}
}
}
There are a fair few more of these properties in the class I'm altering, and some are not used in certain contexts (hence the Laziness), but if they are used they're likely to be called repeatedly.
Unfortunately, the properties are often also used inside the class. This means there is a potential for the private variable (_b) to be used directly by a method without it being initialized.
Is there a way to make only the public property (B) available inside the class, or even an alternative method with the same initialized-when-needed?
This is reposted from Programmers (not subjective enough apparently):
https://softwareengineering.stackexchange.com/questions/34270/best-methods-for-lazy-initialization-with-properties
Well, my recommended solution would be to tell your coworker to use the property, not the field. But you could idiot-proof it to some degree like this:
public class ClassA
{
private Lazy<ClassB> _b = new Lazy<ClassB>(() => new ClassB());
public ClassB B
{
get
{
return _b.Value;
}
}
}
Now it's pretty hard to screw up.
You could consider pushing the lazy properties into a base class to avoid direct access to the backing variable. Not ideal I know. I've always thought this was something lacking in C# i.e. direct support for lazy properties.
#chibacity posted (and subsequently) deleted [and later undeleted :P] an alternative option using an abstract base class. While it may not be ideal in terms of code distribution it does provide a nice encapsulation removing a lot of code clutter making for a cleaner and more succinct ClassA. For instance, you could consider combining the techniques to achieve both goals:
public class ClassB { /* Class to be lazily instantiated */ }
public abstract class BaseA
{
private Lazy<ClassB> _b = new Lazy<ClassB>(() => new ClassB());
public virtual ClassB B { get { return _b.Value; } }
}
public class ClassA : BaseA
{
public override ClassB B { get { return base.B; } }
}
At first glance, it seems like this is more long winded, but when you consider that ClassA which is the class you would be working in and with, this now means that all your references are going through the same property - there is no extraneous unnecessary field causing potential confusion, there's no bypassing the property to reference _b directly and there's no need to tell your coworker which to use... there's only one.
Not saying this is the right way to do this or that this is a pattern that should or shouldn't be followed, I'm just pointing out the advantages of what #chibacity suggested that may otherwise go unnoticed.
It would be nice if you could have implicit lazy loaded properties without having to refer to B.Value... for instance:
[Lazy]
public ClassB B { get; }
or for objects without parameterless constructors
[Lazy(() => new ClassB("Hello", "World"))]
public ClassB B { get; }
or perhaps as #chibacity suggested in a comment
public ClassB B { lazyget; }
or
public ClassB B { lazyget : new ClassB(); }
Alas, I don't think any of these are currently available solutions in any form...

.NET: Determine the type of “this” class in its static method

In a non-static method I could use this.GetType() and it would return the Type. How can I get the same Type in a static method? Of course, I can't just write typeof(ThisTypeName) because ThisTypeName is known only in runtime. Thanks!
If you're looking for a 1 liner that is equivalent to this.GetType() for static methods, try the following.
Type t = MethodBase.GetCurrentMethod().DeclaringType
Although this is likely much more expensive than just using typeof(TheTypeName).
There's something that the other answers haven't quite clarified, and which is relevant to your idea of the type only being available at execution time.
If you use a derived type to execute a static member, the real type name is omitted in the binary. So for example, compile this code:
UnicodeEncoding.GetEncoding(0);
Now use ildasm on it... you'll see that the call is emitted like this:
IL_0002: call class [mscorlib]System.Text.Encoding
[mscorlib]System.Text.Encoding::GetEncoding(int32)
The compiler has resolved the call to Encoding.GetEncoding - there's no trace of UnicodeEncoding left. That makes your idea of "the current type" nonsensical, I'm afraid.
Another solution is to use a selfreferecing type
//My base class
//I add a type to my base class use that in the
//static method to check the type of the caller.
public class Parent<TSelfReferenceType>
{
public static Type GetType()
{
return typeof(TSelfReferenceType);
}
}
Then in the class that inherits it, I make a self referencing type:
public class Child: Parent<Child>
{
}
Now the call type typeof(TSelfReferenceType) inside Parent will get and return the Type of the caller without the need of an instance.
Child.GetType();
You can't use this in a static method, so that's not possible directly. However, if you need the type of some object, just call GetType on it and make the this instance a parameter that you have to pass, e.g.:
public class Car {
public static void Drive(Car c) {
Console.WriteLine("Driving a {0}", c.GetType());
}
}
This seems like a poor design, though. Are you sure that you really need to get the type of the instance itself inside of its own static method? That seems a little bizarre. Why not just use an instance method?
public class Car {
public void Drive() { // Remove parameter; doesn't need to be static.
Console.WriteLine("Driving a {0}", this.GetType());
}
}
I don't understand why you cannot use typeof(ThisTypeName). If this is a non-generic type, then this should work:
class Foo {
static void Method1 () {
Type t = typeof (Foo); // Can just hard code this
}
}
If it's a generic type, then:
class Foo<T> {
static void Method1 () {
Type t = typeof (Foo<T>);
}
}
Am I missing something obvious here?
When your member is static, you will always know what type it is part of at runtime. In this case:
class A
{
public static int GetInt(){}
}
class B : A {}
You cannot call (edit: apparently, you can, see comment below, but you would still be calling into A):
B.GetInt();
because the member is static, it does not play part in inheritance scenarios. Ergo, you always know that the type is A.
For my purposes, I like #T-moty's idea. Even though I have used "self-referencing type" information for years, referencing the base class is harder to do later.
For example (using #Rob Leclerc example from above):
public class ChildA: Parent<ChildA>
{
}
public class ChildB: Parent<ChildB>
{
}
Working with this pattern can be challenging, for example; how do you return the base class from a function call?
public Parent<???> GetParent() {}
Or when type casting?
var c = (Parent<???>) GetSomeParent();
So, I try to avoid it when I can, and use it when I must. If you must, I would suggest that you follow this pattern:
class BaseClass
{
// All non-derived class methods goes here...
// For example:
public int Id { get; private set; }
public string Name { get; private set; }
public void Run() {}
}
class BaseClass<TSelfReferenceType> : BaseClass
{
// All derived class methods goes here...
// For example:
public TSelfReferenceType Foo() {}
public void Bar(TSelfRefenceType obj) {}
}
Now you can (more) easily work with the BaseClass. However, there are times, like my current situation, where exposing the derived class, from within the base class, isn't needed and using #M-moty's suggestion just might be the right approach.
However, using #M-moty's code only works as long as the base class doesn't contain any instance constructors in the call stack. Unfortunately my base classes do use instance constructors.
Therefore, here's my extension method that take into account base class 'instance' constructors:
public static class TypeExtensions
{
public static Type GetDrivedType(this Type type, int maxSearchDepth = 10)
{
if (maxSearchDepth < 0)
throw new ArgumentOutOfRangeException(nameof(maxSearchDepth), "Must be greater than 0.");
const int skipFrames = 2; // Skip the call to self, skip the call to the static Ctor.
var stack = new StackTrace();
var maxCount = Math.Min(maxSearchDepth + skipFrames + 1, stack.FrameCount);
var frame = skipFrames;
// Skip all the base class 'instance' ctor calls.
//
while (frame < maxCount)
{
var method = stack.GetFrame(frame).GetMethod();
var declaringType = method.DeclaringType;
if (type.IsAssignableFrom(declaringType))
return declaringType;
frame++;
}
return null;
}
}
EDIT
This methods will works only when you deploy PDB files with the executable/library, as markmnl pointed out to me.
Otherwise will be a huge issue to be detected: works well in developement, but maybe not in production.
Utility method, simply call the method when you need, from every place of your code:
public static Type GetType()
{
var stack = new System.Diagnostics.StackTrace();
if (stack.FrameCount < 2)
return null;
return (stack.GetFrame(1).GetMethod() as System.Reflection.MethodInfo).DeclaringType;
}

Categories

Resources