An interviewer asked me the question below
public class A
{
public string GetName()
{
return "A";
}
}
public class B : A
{
public string GetName()
{
return "B";
}
}
public class C : B()
{
public string GetName
{
return "C";
}
}
What are the outputs of
A a = new A();
a.GetName();
a = new B();
a.GetName();
a = new C();
a.GetName();
I said all will give "A". Then he said i need to correct my basics.
Your answer is correct; there is no method overriding applied due to the absence of virtual and override keywords.
So in all three cases it returns output A.
If you want to apply proper method overriding, you need to apply virtual to the base class methods and override to the child class methods where you are overriding base class method.
Try This:
class Program
{
static void Main(string[] args)
{
A a = new A();
Console.WriteLine(a.GetName());
a = new B();
Console.WriteLine(a.GetName());
a = new C();
Console.WriteLine(a.GetName());
}
}
public class A
{
public virtual string GetName()
{
return "A";
}
}
public class B : A
{
public override string GetName()
{
return "B";
}
}
public class C : B
{
public override string GetName()
{
return "C";
}
}
OUTPUT:
A
B
C
You are assigning all objects (new A(), new B(), new C()) to the variable A a. Since they are all being viewed as type A and the method is not virtual, then the implementation for type A is invoked and "A" is returned.
This link provides a more detailed explanation with samples.
public class B : A
{
public string GetName()
{
return "B";
}
}
is same as
public class B : A
{
public new string GetName()
{
return "B";
}
}
which will hide the method by calling the interface or baseclass,
var b = new B();
b.GetName() ==> "B"
while
A a = new B();
a.GetName() ===> "A"
this is dangrous and I saw lots of people write such code without knowing what's the difference between new and override
Related
Suppose I have two implementations of a base class:
public class Base {
public string Stringify() { return "I am a member of base class"; }
}
public class A : Base {
public void DoAThing() {...};
}
public class B : Base {
public void DoBThing(int anInteger) {...};
}
Suppose I want to put many instances of Base in a list, so that I can loop over them and call Stringify() on each, and make use of their shared functionality.
static void Main(string[] args)
{
A thing1 = new A();
B thing2 = new B();
B thing3 = new B();
List<Base> list = new List<Base> {thing1, thing2, thing3};
foreach(Base base in list) { Console.WriteLine(base.Stringify()); }
}
Now suppose there are many many Base objects, such that maintaining the individual thing references to each one is not realistic. Would there be any way, via only the list, to regain the DoAThing() or DoBThing() functionality that is lost by the abstraction without having to use explicit downcasting and reflection?
This feels like it would be a common enough occurance, so I am wondering if there is a design flaw or established pattern I am missing here that would help in this situation.
If you debug, you can notice every object of the list mantains its' class.
This way:
class Program
{
static void Main(string[] args)
{
A thing1 = new A();
B thing2 = new B();
B thing3 = new B();
List<Base> list = new List<Base> { thing1, thing2, thing3 };
foreach (Base bas in list) {
Console.WriteLine(bas.Stringify());
if(bas is A)
{
((A)bas).DoAThing();
}
else if (bas is B)
{
((B)bas).DoBThing(1);
}
else
{
//IDK
}
}
}
}
public abstract class Base
{
public string Stringify() { return "I am a member of base class"; }
}
public class A : Base
{
public void DoAThing()
{
}
}
public class B : Base
{
public void DoBThing(int anInteger)
{
}
}
I have a base class with a long chain of inheritance. I pass around instances of a child class in a variable with the type of the base class. Can I do a ToString on the instance of the child class and have the child's ToString run (not the parents)?
Here is my attempt:
namespace Abc
{
class A
{
string strA = "A";
public virtual string ToString() { return strA; }
}
class B : A
{
string strB = "B";
public virtual string ToString() { return base.ToString() + strB; }
}
class C : B
{
string strC = "C";
public virtual string ToString() { return base.ToString() + strC; }
}
class Program
{
static void Main(string[] args)
{
A a = new C();
System.Console.WriteLine(a.ToString());
System.Console.ReadLine();
}
}
}
This program outputs A. I thought that adding the virtual keyword would have it output ABC. How can I get this result without casting? Casting requires me to know the type at compile time.
You don't need to declare virtual at each level, you only need to do that in the class that declares it, child classes should do override instead. Because ToString() is defined in Object which is what A is implicitly derived from all off your classes should just use override
class A
{
string strA = "A";
public override string ToString() { return strA; }
//Added a example of somthing not declared in Object
public virtual string Example() { return "I am in A!"; }
}
class B : A
{
string strB = "B";
public override string ToString() { return base.ToString() + strB; }
//Notice the override instead of the virtual.
public override string Example() { return "I am in B!"; }
}
class C : B
{
string strC = "C";
public override string ToString() { return base.ToString() + strC; }
public override string Example() { return "I am in C!"; }
}
What was causing your error is you where Shadowing ToString(), you should have gotten a compiler warning telling you that you where doing that and you needed to use the new keyword to get rid of the compiler warning and explicitly state that you wanted to shadow and not override the method.
Code to demonstrate the problem:
static void Main(string[] args)
{
var a = new A();
var b = new B();
Base<>[] all = new Base<>[] { a, b }; // doesn't work
}
class Base<T>
{
public string Caption { get { return typeof(T).ToString(); } }
}
class A : Base<A> { }
class B : Base<B> { }
Perhaps I went the wrong direction. Idea was to move Caption into base class (Base become generic). Non-generic version works without problems:
var all = new Base[] { a, b }; // no problems for as long as Base is not generic
There's no Type<?> in C# - you always have to specify a concrete generic type.
The only way around this is to make Base<T> inherit a non-generic base-class, or implement a non-generic interface. You could then use that as the type of the array.
EDIT:
In your case this is extremely simple, since the part of the interface you want doesn't include the generic type argument. So you can simply do either:
public abstract class Superbase
{
public abstract string Caption { get; }
}
public class Base<T>: Superbase
{
public override string Caption { get { return typeof(T).Name; } }
}
Or, using an interface:
public interface IBase
{
string Caption { get; }
}
public class Base<T>: IBase
{
public string Caption { get { return typeof(T).Name; } }
}
Your array would then be Superbase[] or IBase[], respectivelly. In both cases, you can see that I'm not actually providing an implementation - both the declarations are "abstract", in a sense.
In general, I'm trying to keep the non-generic stuff in a non-generic base class, rather than stuffing it in the derived generic classes. It just feels more clean :)
based on #Luaan ideea, here is an implementation:
class Program
{
static void Main(string[] args)
{
var a = new A();
var b = new B();
var arr = new Base[] { a, b};
foreach (var obj in arr)
Console.WriteLine(obj.Caption);
Console.ReadKey();
}
}
public class Base<T> : Base
{
public override string Caption
{
get { return typeof (T).ToString(); }
}
}
public class A : Base<A> { }
public class B : Base<B> { }
public abstract class Base
{
public abstract string Caption { get; }
}
Instead of trying to use inheritance (which will lead to more problems down the line), use an extension method instead:
public interface IClassAORClassB {}
class A : IClassAORClassB { }
class B : IClassAORClassB { }
public static class Captions
{
public static string Caption<T>(this T obj) where T : IClassAORClassB
{
return obj.GetType().ToString();
}
}
static void Main(string[] args)
{
var a = new A();
var b = new B();
var all = new IClassAORClassB[] { a, b }; // works just fine
Console.WriteLine(all[0].Caption()); // prints A
Console.WriteLine(all[1].Caption()); // prints B
}
I have an abstract base class Base which has some common properties, and many derived ones which implement different logic but rarely have additional fields.
public abstract Base
{
protected int field1;
protected int field2;
....
protected Base() { ... }
}
Sometimes I need to clone the derived class. So my guess was, just make a virtual Clone method in my base class and only override it in derived classes that have additional fields, but of course my Base class wouldn't be abstract anymore (which isn't a problem since it only has a protected constructor).
public Base
{
protected int field1;
protected int field2;
....
protected Base() { ... }
public virtual Base Clone() { return new Base(); }
}
public A : Base { }
public B : Base { }
The thing is, since I can't know the type of the derived class in my Base one, wouldn't this lead to have a Base class instance even if I call it on the derived ones ? (a.Clone();) (actually after a test this is what is happening but perhaps my test wasn't well designed that's why I have a doubt about it)
Is there a good way (pattern) to implement a base Clone method that would work as I expect it or do I have to write the same code in every derived class (I'd really like to avoid that...)
Thanks for your help
You can add a copy constructor to your base class:
public abstract Base
{
protected int field1;
protected int field2;
protected Base() { ... }
protected Base(Base copyThis) : this()
{
this.field1 = copyThis.field1;
this.field2 = copyThis.field2;
}
public abstract Base Clone();
}
public Child1 : Base
{
protected int field3;
public Child1 () : base() { ... }
protected Child1 (Child1 copyThis) : base(copyThis)
{
this.field3 = copyThis.field3;
}
public override Base Clone() { return new Child1(this); }
}
public Child2 : Base
{
public Child2 () : base() { ... }
protected Child (Child copyThis) : base(copyThis)
{ }
public override Base Clone() { return new Child2(this); }
}
public Child3 : Base
{
protected int field4;
public Child3 () : base() { ... }
protected Child3 (Child3 copyThis) : base(copyThis)
{
this.field4 = copyThis.field4;
}
public override Base Clone()
{
var result = new Child1(this);
result.field1 = result.field2 - result.field1;
}
}
Just override the Clone and have another method to CreateInstance then do your stuff.
This way you could have only Base class avoiding generics.
public Base
{
protected int field1;
protected int field2;
....
protected Base() { ... }
public virtual Base Clone()
{
var bc = CreateInstanceForClone();
bc.field1 = 1;
bc.field2 = 2;
return bc;
}
protected virtual Base CreateInstanceForClone()
{
return new Base();
}
}
public A : Base
{
protected int fieldInA;
public override Base Clone()
{
var a = (A)base.Clone();
a.fieldInA =5;
return a;
}
protected override Base CreateInstanceForClone()
{
return new A();
}
}
I did something similar as Alexander Simonov, but perhaps simpler. The idea is (as I said in a comment) to have just one Clone() in the base class and leave all the work to a virtual CloneImpl() which each class defines as needed, relying on the CloneImpl()s of the base classes.
Creation of the proper type is left to C#'s MemberwiseClone() which will do whatever it takes for the object that's calling. This also obviates the need for a default constructor in any of the classes (none is ever called).
using System;
namespace CloneImplDemo
{
// dummy data class
class DeepDataT : ICloneable
{
public int i;
public object Clone() { return MemberwiseClone(); }
}
class Base: ICloneable
{
protected virtual Base CloneImpl()
{
// Neat: Creates the type of whatever object is calling.
// Also obviates the need for default constructors
// (Neither Derived1T nor Derived2T have one.)
return (Base)MemberwiseClone();
}
public object Clone()
{
// Calls whatever CloneImpl the
// actual calling type implements.
return CloneImpl();
}
}
// Note: No Clone() re-implementation
class Derived1T : Base
{
public Derived1T(int i) { der1Data.i = i; }
public DeepDataT der1Data = new DeepDataT();
protected override Base CloneImpl()
{
Derived1T cloned = (Derived1T)base.CloneImpl();
cloned.der1Data = (DeepDataT)der1Data.Clone();
return cloned;
}
}
// Note: No Clone() re-implementation.
class Derived2T : Derived1T
{
public Derived2T(int i1, int i2) : base(i1)
{
der2Data.i = i2;
}
public string txt = string.Empty; // copied by MemberwiseClone()
public DeepDataT der2Data = new DeepDataT();
protected override Base CloneImpl()
{
Derived2T cloned = (Derived2T)base.CloneImpl();
// base members have been taken care of in the base impl.
// we only add our own stuff.
cloned.der2Data = (DeepDataT)der2Data.Clone();
return cloned;
}
}
class Program
{
static void Main(string[] args)
{
var obj1 = new Derived2T(1,2);
obj1.txt = "this is obj1";
var obj2 = (Derived2T)obj1.Clone();
obj2.der1Data.i++;
obj2.der2Data.i++; // changes value.
obj2.txt = "this is a deep copy"; // replaces reference.
// the values for i should differ because
// we performed a deep copy of the DeepDataT members.
Console.WriteLine("obj1 txt, i1, i2: " + obj1.txt + ", " + obj1.der1Data.i + ", " + obj1.der2Data.i);
Console.WriteLine("obj2 txt, i1, i2: " + obj2.txt + ", " + obj2.der1Data.i + ", " + obj2.der2Data.i);
}
}
}
Output:
obj1 txt, i1, i2: this is obj1, 1, 2
obj2 txt, i1, i2: this is a deep copy, 2, 3
You could do something like this:
public class Base<T> where T: Base<T>, new()
{
public virtual T Clone()
{
T copy = new T();
copy.Id = this.Id;
return copy;
}
public string Id { get; set; }
}
public class A : Base<A>
{
public override A Clone()
{
A copy = base.Clone();
copy.Name = this.Name;
return copy;
}
public string Name { get; set; }
}
private void Test()
{
A a = new A();
A aCopy = a.Clone();
}
But i doubt that it will bring something useful. I'll create another example..
I got another idea using the Activator class:
public class Base
{
public virtual object Clone()
{
Base copy = (Base)Activator.CreateInstance(this.GetType());
copy.Id = this.Id;
return copy;
}
public string Id { get; set; }
}
public class A : Base
{
public override object Clone()
{
A copy = (A)base.Clone();
copy.Name = this.Name;
return copy;
}
public string Name { get; set; }
}
A a = new A();
A aCopy = (A)a.Clone();
But i would go for the Alexander Simonov answer.
If performance is not important for your case, you can simplify your code by creating just one general clone method which can clone whatever to whatever if properties are same:
Base base = new Base(){...};
Derived derived = XmlClone.CloneToDerived<Base, Derived>(base);
public static class XmlClone
{
public static D CloneToDerived<T, D>(T pattern)
where T : class
{
using (var ms = new MemoryStream())
{
using (XmlWriter writer = XmlWriter.Create(ms))
{
Type typePattern = typeof(T);
Type typeTarget = typeof(D);
XmlSerializer xmlSerializerIn = new XmlSerializer(typePattern);
xmlSerializerIn.Serialize(writer, pattern);
ms.Position = 0;
XmlSerializer xmlSerializerOut = new XmlSerializer(typeTarget, new XmlRootAttribute(typePattern.Name));
D copy = (D)xmlSerializerOut.Deserialize(ms);
return copy;
}
}
}
}
Found this question while trying to solve this exact problem, had some fun with LINQPad while at it.
Proof of concept:
void Main()
{
Person p = new Person() { Name = "Person Name", Dates = new List<System.DateTime>() { DateTime.Now } };
new Manager()
{
Subordinates = 5
}.Apply(p).Dump();
}
public static class Ext
{
public static TResult Apply<TResult, TSource>(this TResult result, TSource source) where TResult: TSource
{
var props = typeof(TSource).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var p in props)
{
p.SetValue(result, p.GetValue(source));
}
return result;
}
}
class Person
{
public string Name { get; set; }
public List<DateTime> Dates { get; set; }
}
class Manager : Person
{
public int Subordinates { get; set; }
}
Lets suppose we have these classes:
class A {
public string attr = "Class A";
public static void getAttribute(){
self currentClass = new self(); // equivalent to php
Console.Write("Attribute : " + currentClass.attr);
}
}
Class B : A {
public string attr = "Class B";
}
B = new B();
B.getAttribute();
I want B.getAttribute(); to print Attribute: Class B. How can I do this?
This is fundamentally impossible.
B.getAttribute() compiles to A.getAttribute().
I probably know what you are trying to do, but I have to tell you that this kind of PHP approach makes no sense in C#. I discourage you from using it.
public class A
{
private String attr = "Class A";
public static String getAttribute()
{
return (new A()).attr;
}
}
public class B : A
{
private String attr = "Class B";
public static String getAttribute()
{
return (new B()).attr;
}
}
You get the current class instance by the 'this' keyword. Obviously you cannot access that in a static method since by definition a static method executes without the context of a particular instance.
On the other hand, to access a member variable/property/method from inside the same class, you don't need the 'this' keyword at all, since it's implicit.
If you're asking how to do something like that in C#, I think the answer would be along these lines:
public class A
{
public virtual string attr
{
get { return "Class A" }
}
public void getAttribute(){
Console.Write("Attribute : " + attr);
}
}
public class B : A
{
public override string attr
{
get { return "Class B"; }
}
}
var b = new B();
b.getAttribute();
Regarding my comment in the other answer, if you needed getAttribute to be static, you could implement it this way:
public static void getAttribute(A obj){
Console.Write("Attribute : " + obj.attr);
}
You would then call it like this:
var b = new B();
A.getAttribute(b);