Does "this" always know the calling object? - c#

I would like to avoid writing the same line of code in all my derived classes. I have the following structure:
using Newtonsoft.Json;
public class BaseClass
{
public string BaseProperty { get; set; }
public string Serialize() { return JsonConvert.SerializeObject(this); }
}
public class DerivedClass : BaseClass
{
public string DerivedProperty { get; set; }
}
What happens when Serialize() is called from DerivedClass? Is this smart enough to know that the child object contains an extra property? Or, am I limited to writing this same line of code in each child of BaseClass?

Some language features / behaviors are easy to experiment with... Considering the following code:
public class A
{
public string WhoAmI => this.ToString();
}
public class B:A { }
Your question is equivalent to asking what Console.WriteLine(new B().WhoAmI) prints out?
Well, if in doubt, run it and see... it takes less than 1 minute.
this is a reference to an object, and behaves as any other reference, it simply has a special name.
Considere the following:
A a = new B();
Now you have a B instance referenced by an A typed reference a, but the instance is still a B. In your case this inside BaseClass is simply a BaseClass reference to whatever instance has been created. Do not confuse the type of a reference pointing to an object with the type of the object itself, they need not be the same.

Related

How to understand this generic class defination with such type parameters constrain define in C# [duplicate]

Yesterday, I was explaining C#'s generic constraints to my friends. When demonstrating the where T : CLASSNAME constraint, I whipped up something like this:
public class UnusableClass<T> where T : UnusableClass<T>
{
public static int method(T input){
return 0;
}
}
And was really surprised to see it compile. After a bit of thinking, however, I figured it was perfectly legal from the point of view of the compiler - UnusableClass<T> is as much of a class as any other that can be used in this constraint.
However, that leaves a couple of questions: how can this class ever be used? Is it possible to
Instantiate it?
Inherit from it?
Call its static method int method?
And, if yes, how?
If any of these is possible, what would the type of T be?
This approach is widely used in Trees and other Graph-like structures. Here you say to compiler, that T has API of UnusableClass. That said, you can implement TreeNode as follows:
public class TreeNode<T>
where T:TreeNode<T>
{
public T This { get { return this as T;} }
public T Parent { get; set; }
public List<T> Childrens { get; set; }
public virtual void AddChild(T child)
{
Childrens.Add(child);
child.Parent = This;
}
public virtual void SetParent(T parent)
{
parent.Childrens.Add(This);
Parent = parent;
}
}
And then use it like this:
public class BinaryTree:TreeNode<BinaryTree>
{
}
Well.
public class Implementation : UnusableClass<Implementation>
{
}
is perfectly valid, and as such makes
var unusable = new UnusableClass<Implementation>();
and
UnusableClass<Implementation>.method(new Implementation());
valid.
So, yes, it can be instantiated by supplying an inheriting type as the type parameter, and similarly with the call to the static method. It's for instance useful for tree-like structures where you want to generically specify the type of children the node has, while it being the same type itself.
If any of these is possible, what would the type of T be?
They are all possible, and you are the one who is gonna determine what is the type of T.For example let's assume there is a type that inherits from UnusableClass<T>
class Foo : UnusableClass<Foo> { }
Now you can instantiate UnusableClass<Foo> because Foo satisfies the constraint:
UnusableClass<Foo> f = new UnusableClass<Foo>();
Then the type of T become Foo and if you try to call method you need to pass an instance of Foo.

Serialize Class obtained using Reflection to XML

I have a file that looks like the following:
public abstract class TestStep
{
public abstract bool DoWork();
public abstract List<TestStep> PrerequisiteSteps { get; set; }
public abstract string DisplayForm { get; }
}
class TestFunctions
{
public class A : TestStep
{
public override string DisplayForm { get { return "MainForm; } }
// remaining implementation goes here...
}
public class B : TestStep { // some implementation }
public class C : TestStep { // some implementation }
public static void NextStep() { }
}
I'd like to serialize the classes A, B, and C to an XML file. I can manually add instances of these classes to a List<TestStep> object and pass that to an XML serializer, but I'd like to programmatically accomplish this because I might add or remove classes in TestFunctions in the future. As a result, I've found that I can use reflection to get an array of the functions:
Type type = (typeof(TestEngineFunctions));
Type[] testEngineFunctions = type.GetNestedTypes(BindingFlags.Public);
However I'm not sure how to proceed from here. I have access to the name of the functions, I can get their properties as well, but ultimately I don't have an actual object to serialize.
Am I on the right track or is there another method better suited for this?
You can get a new instance of the objects like this:
ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);
Since you may not know the ObjectType before run time you could use the dynamic type and don't cast:
dynamic instance = Activator.CreateInstance(objectType);
However, if you attempt to serialize right after you instantiate you'll just get the default values of the object in your XML.

It's possible pass subclass of superclass in <T>?

I have a class named GenericDao
internal class GenericDao<T> : IGenericDao<T> {
}
The two class of objects:
public class Empresa {
}
public class Assessoria : Empresa {
}
And i have one EmpresaDao:
public class EmpresaDao {
private GenericDao<Empresa> parent { get; set; }
public EmpresaDao() {
this.parent = new GenericDao<Empresa>();
}
}
How to instantiate the GenericDao using the subclass Assessoria? I do something like this, but not work:
public class EmpresaDao {
private GenericDao<Empresa> parent { get; set; }
public EmpresaDao(Type type) {
if (type == typeof(Assessoria)) {
this.parent = new GenericDao<Assessoria>();
} else {
this.parent = new GenericDao<Empresa>();
}
}
}
In short, you can't, really. However, you can cheat a little if you use a base interface that is not generic, or you use C# 4 and use a base interface that is generic, but with a covariant or contravariant (depending on need) type parameter. For the first case:
interface IGenericDaoBase {
}
interface IGenericDao<T> : IGenericDaoBase {
}
public class EmpresaDao {
private IGenericDaoBase parent { get; set; }
public EmpresaDao(Type type) {
// same as before
}
}
Admittedly, it might be better to rethink your design. Perhaps EmpresaDao can take a generic parameter itself, which would be used like so:
public class EmpresaDao<T> where T : Empresa {
private GenericDao<T> parent { get; set; }
public EmpresaDao() {
this.parent = new GenericDao<T>();
}
}
EDIT: In fact, the more I think about it, the more I believe this latter solution is the way to go. The type parameter in the constructor is fulfilling the same role as the type parameter on the class signature. So you won't have to change the calling code much, except to pass in a generic parameter instead of a Type object.
It is a good thing that your try don't work, you would introduce a bug if it did.
Suppose I have variables a, b both of type EmpresaDao. a is initilized with a Empresa parent and b is initialized with a Assessoria parent. Since a and b are of the same type, it should be possible to use one in place of the other everywhere. Suppose Assessoria but not Empresa has a method assess(). But you expect b.parent to be Assessoria so you want to call b.parent.assess() but you cannot call a.parent.assess() Which means a and b should not be of the same type in the first place.
The solution depends on whether you will ever call .parent.assess() :
a) If you will never call .parent.assess() within EmpresaDao class, let compile time type of the parent always be Empresa. Here is a solution :
public class EmpresaDao
{
private Empresa parent {get; set; }
public EmpresaDao(Func<Empresa> parentConstructor)
{
this.parent = parentConstructor();
}
}
static main()
{
var withEmpresaParent = new EmpresaDao(() => new Empresa());
var withAssessoriaParent = new EmpresaDao(() => new Assessoria());
..
}
b) You will sometimes call .parent.assess() within EmpresaDao class. Then you should make the EmpresaDao generic, as #siride said:
public class EmpresaDao<T> where T : Empresa
{
private T parent {get; set;}
}
However, it is still the case that you will have to make run time checks on parent before calling .parent.assess() Which means there is still something wrong in your design. But there is not enough information to decide what. Maybe .assess() method should be private and not to be called from outside (i.e. Assessoria should be a decorator on Empresa: subclass but with the same interface) Maybe "Empresa holding EmpresaDao" and "Assessoria holding EmpresaDao" should be two different classes. (implementing the same interface, probably)
Edit: Now I realize that, in my solution I mistakenly made the type of parent Empresa or Assessoria instead of GenericDao or GenericDao. I believe my main is still valid though.

How to get a reference to an instance of a derived class from within a base class

.Net 3.5, using C#
I have an instance of a class (A) that has been called via a virtual method from a derived class (B). Within the method (a method of class A) I have discovered the Type of class B that has made the call, and using reflection I have examined class B and discovered a property whose value I want to access.
Is there any way via reflection to get the instance reference to class B? The only object I have is my ‘this’ reference.
[ Edit ]
By way of explaining that I'm not totally nuts for needing to do this: My class is T4NmpBase (class A). I have no control over the class in which I am inheriting (TextTransformation) or the class that inherits from me (TextTemplating - class B). I would like to use the "Host" property if it exits but do not want to put any burden on the programmer who is writing the text templating code that generates the TextTransformation class.
//
// this is my class
//
public abstract partial class T4NmpBase : Microsoft.VisualStudio.TextTemplating.TextTransformation {
public override void Initialize()
{
//
// determine derived class info and get value of "Host" property if it exists
//
}
}
//
// this class is generated by T4 in a project that I have no control over
//
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.TextTemplating", "10.0.0.0")]
public partial class PPTest : T4_NMP_Base.T4NmpBase {
public virtual global::Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost Host { ... }
public override void Initialize()
{
base.Initialize();
}
}
In your case (assuming I follow correctly) your this reference is really your class (B) type, so you can use that to get the value of the property. So, just to make sure I follow correctly, you've got something that looks like:
public class ClassA
{
public virtual void VirtualMethod()
{
// Do your property investigation here
}
}
public class ClassB: ClassA
{
public override void VirtualMethod()
{
// Code for ClassB
}
}
And you are invoking the virtual method using something like:
ClassA instance = new ClassB();
instance.VirtualMethod()
So if that is the case then you should be able to get the value of the property by:
PropertyInfo proeprtyOnClassB // Assume you got this already via reflection
object propertyValue = propertyOnClassB.GetGetMethod().Invoke(this,null);
This sounds like a real problem with your design.
Is it possible to take Class B's property in question and make it a virtual property of Class A? Then you can override it in B but still access B's property from A. For example:
class A
{
public virtual string P
{
get { return "A"; }
}
public A()
{
Console.WriteLine(this.P);
}
}
class B : A
{
public override string P
{
get { return "B"; }
}
public B() : base() { }
}
When using:
B b = new B(); // prints "B"
If I understand correctly, from class A you want to access the functionality of the current instance through its concrete type B. Unless the member is not accessible to A because it's non-public, defined in another assembly, etc you don't need reflection. The following will work if the code in class A can see the members of derived class B.
B thisAsB = this as B;
if (thisAsB != null) {
// ...
}
But it does call into question the design of the class because class A should not have to know anything about its subclasses.

C# do nested classes need to be instantiated?

In the following scenario:
public class outerclass
{
public innerClass Ic
{get;set}
public class innerClass
{
}
}
Do you need to instantiate the inner class property before assigning values to it, like this?
public class outerclass
{
public outerclass()
{
this.Ic = new innerClass();
}
public innerClass Ic
{get;set}
public class innerClass
{
}
}
It doesn't matter in what scope class has been declared - you should always work with classes in the same manner: before interacting with a particular class instance you have to create it using new operator.
Yes, unlike a base class you need to instantiate an inner class if you wish to use it.
You can prove this to yourself quite easily by trying it:
public class OuterClass
{
public InnerClass Ic { get; set; }
public class InnerClass
{
public InnerClass()
{
Foo = 42;
}
public int Foo { get; set; }
}
}
public class Program
{
static void Main()
{
Console.WriteLine(new OuterClass().Ic.Foo);
}
}
The above code throws a NullReferenceException because Ic has not been assigned.
I would also advise you to follow the Microsoft naming convention and use pascal case for type names.
In this case the answer doesn't depend on the fact that the class is defined inside your outer class. Because you used the automatic getter/setter, a hidden backing field is used for the property Ic. Like all fields of reference type, this field has a default value of null. Thus if you try to access the members of Ic without setting it to refer to some instance, you can expect a NullReferenceException.
Everything I just said would still be true even if innerClass was defined somewhere else.
No, the property is an instance of the class. The set would set a new instance anyway. No need to construct one unless you want to make sure the get never returns null.

Categories

Resources