how to pass value to abstract class for changing name property - c#

I had an interview today and it had the following code with 2 questions. Could someone please help me answer the two questions below on the below code snippet. (Some minor syntax error if seen please ignore as I tried to remember it from mind)....
Question 1 - Change the name to "NameChange".
Question 2 - Override the abstract method in derived class.
public abstract Class A
{
public string Name { get { return GetName(); } };
public virtual string GetName()
{
return this.Name.ToString();
}
protected abstract void SomeMethod();
}
public class B : A
{
//Change name to "NameChange"
//override the abstract method here
}

I'm not sure whether there's a hidden question or those are as simple as this. For the first question, there're two answers (method 1 and 2):
public class B : A
{
//Method 1
public new string Name { get { return "NameChange"; } }
//Method 2
public override string GetName()
{
return "NameChange"; // return whatever you want
}
protected override void SomeMethod() // override abstract method
{
// do something
}
}
In Method 1, you are effectively hiding the implementation of Name of the base class. In Method 2, you are overriding the implementation of GetName.

This should answer both questions:
public class B : A
{
//override Method
public override string GetName()
{
return "NameChange";
}
// override abstract Method
protected override void SomeMethod()
{
//code here...
}
}

I'm not sure if i get it right, but is that what you need?
public class B : A
{
public string NameChange => base.GetName();
protected override void SomeMethod()
{
throw new NotImplementedException();
}
}
Or maybe this one?
public class B : A
{
public override string GetName()
{
return "NameChange";
}
protected override void SomeMethod()
{
throw new NotImplementedException();
}
}

I am not sure what is the point here but if they insist on changing the value of property name, new constraint can be the trick here.
You can find the implementation following;
public abstract class A
{
public string Name { get { return GetName(); } }
public virtual string GetName()
{
return this.Name.ToString();
}
protected abstract void SomeMethod();
}
public class B : A
{
public B() : base()
{
SomeMethod();
}
public new string Name { get; set; }
public override string GetName()
{
return Name;
}
protected override void SomeMethod()
{
this.Name = "Ayberk";
}
}
public class Program
{
public static void Main(string[] args)
{
//Your code goes here
B b = new B();
Console.WriteLine(b.GetName());
}
}
You can try it here

Related

Downcasting a List<AbstractClass> object to what the object actually is

I have a ParentClass. Two classes are inherit from it, FirstChildClass and SecondChildClass. A class MultipleValueTypes contains a Dictionary and a method that adds values to it. My intention is to be able to pass values of different classes, which inherit from the same abstract class to the value parameter of the Dictionary. Therefore, I initialize the dictionary with the value List<ParentClass> so that I would be able to add objects made with the child classes to the Dictionary. I can do this, but I cannot access them, therefore in the abstract class I create a way to tell them apart, a virtual method that both the children classes override to return their own class type.
I test the values they return against the enum itself and based on whether the condition is fulfilled, the object would be casted as what it is instead of a List<ParentClass>. Is this the wrong approach? Is this impossible?
I think it should work, because in my thinking the FirstObject and SecondObject are still objects of their respective classes, so casting should work and I should be able to access the overridden method.
What doesn't work: I cannot access the method that returns what type of class it is, because it only gets methods from the List<ParentClass>.
What I've tried so far: searching for a way to access the method, but I did not find any.
What I still need help with: everything mentioned above.
public abstract class ParentClass
{
public string Name { get; set; }
public ParentClass(string Name)
{
this.Name = Name;
}
public enum ChildClasses
{
NoChildClass = 0,
FirstChildClass = 1,
SecondChildClass = 2
}
public virtual ChildClasses TypeOfClass()
{
return ChildClasses.NoChildClass;
}
}
public class FirstChildClass : ParentClass
{
private string _randomvalue;
public string RandomValue { get => _randomvalue; set => _randomvalue = value; }
public FirstChildClass(string Name) : base(Name)
{
}
public void ReturnMessage()
{
Console.WriteLine("This is the FirstChildClass");
}
public override ChildClasses TypeOfClass()
{
return ChildClasses.FirstChildClass;
}
}
public class SecondChildClass : ParentClass
{
private string _randomvalue;
public string RandomValue { get => _randomvalue; set => _randomvalue = value; }
public SecondChildClass(string Name) : base(Name)
{
}
public void ReturnMessage()
{
Console.WriteLine("This is the SecondChildClass");
}
public override ChildClasses TypeOfClass()
{
return ChildClasses.SecondChildClass;
}
}
class MultipleValueTypes
{
public Dictionary<string, List<ParentClass>> ADictionary = new Dictionary<string, List<ParentClass>>();
public void AddObject(string Name, ParentClass variable)
{
if (!ADictionary.ContainsKey(Name))
{
ADictionary.Add(Name, new List<ParentClass>());
}
ADictionary[Name].Add(variable);
}
}
class Program
{
static void Main(string[] args)
{
FirstChildClass FirstObject = new FirstChildClass("FirstObject");
SecondChildClass SecondObject = new SecondChildClass("SecondObject");
MultipleValueTypes TestDictionary = new MultipleValueTypes();
TestDictionary.AddObject("FirstObject", FirstObject);
TestDictionary.AddObject("SecondObject", SecondObject);
if(TestDictionary.ADictionary["FirstObject"].TypeOfClass() == ParentClass.ChildClasses.FirstChildClass) ///List<ParentClass>' does not contain a definition for 'TypeOfClass' and no accessible extension method 'TypeOfClass' accepting a first argument of type 'List<ParentClass>' could be found (are you missing a using directive or an assembly reference?)
{
TestDictionary.ADictionary["FirstObject"] = (FirstChildClass)TestDictionary.ADictionary["FirstObject"]; ///Cannot convert type 'System.Collections.Generic.List<Dictionary.ParentClass>' to 'Dictionary.FirstChildClass
}
}
}
You forgot to use indexer of the list value of the key of the dictionary here:
==> TestDictionary.ADictionary["FirstObject"][0]
Here is your code now refactored too:
class Program
{
static void Main(string[] args)
{
var FirstObject = new FirstChildClass("FirstObject");
var SecondObject = new SecondChildClass("SecondObject");
FirstObject.ReturnMessage();
SecondObject.ReturnMessage();
MultipleValueTypes TestDictionary = new MultipleValueTypes();
TestDictionary.AddObject("FirstObject", FirstObject);
TestDictionary.AddObject("SecondObject", SecondObject);
if ( TestDictionary.ADictionary["FirstObject"][0].TypeOfClass()
== ParentClass.ChildClasses.FirstChildClass )
{
TestDictionary.ADictionary["FirstObject"][0]
= (FirstChildClass)TestDictionary.ADictionary["FirstObject"][0];
}
Console.ReadKey();
}
}
public abstract class ParentClass
{
public string Name { get; set; }
public string RandomValue { get; set; }
public ParentClass(string Name)
{
this.Name = Name;
}
public virtual void ReturnMessage()
{
Console.WriteLine($"This is the {this.GetType().Name} instance");
}
public virtual ChildClasses TypeOfClass()
{
return ChildClasses.NoChildClass;
}
public enum ChildClasses
{
NoChildClass = 0,
FirstChildClass = 1,
SecondChildClass = 2
}
}
public class FirstChildClass : ParentClass
{
public FirstChildClass(string Name)
: base(Name)
{
}
public override ChildClasses TypeOfClass()
{
return ChildClasses.FirstChildClass;
}
}
public class SecondChildClass : ParentClass
{
public SecondChildClass(string Name)
: base(Name)
{
}
public override ChildClasses TypeOfClass()
{
return ChildClasses.SecondChildClass;
}
}
class MultipleValueTypes
{
public readonly Dictionary<string, List<ParentClass>> ADictionary
= new Dictionary<string, List<ParentClass>>();
public void AddObject(string Name, ParentClass variable)
{
if ( !ADictionary.ContainsKey(Name) )
{
ADictionary.Add(Name, new List<ParentClass>());
}
ADictionary[Name].Add(variable);
}
}
If the intention is to cast the whole list from List<ParentClass> to List<FirstChildClass> and List<SecondChildClass>, then Linq is your friend, just use the Cast function:
List<FirstChildClass> firstChildClasses = TestDictionary.ADictionary["FirstObject"]
.Cast<FirstChildClass>().ToList();
List<SecondChildClass> secondChildClasses = TestDictionary.ADictionary["SecondObject"]
.Cast<SecondChildClass>().ToList();

Method Override with some condition in Console application

I am creating one console application. I have one class in which I wrote some methods. Now I want to override some methods of that class in a different class. But this should be override only if condition satisfied.
For example,
public partial Class MainClass
{
public string GetPath()
{
string temp = Method1();
return temp;
}
protected virtual string Method1()
{
//logic
}
}
If some condition satisfied then only overridden method should be called
public partial class ChildClass : MainCLass
{
public override void Method1()
{
//MY Logic
}
}
How can I achieve this? Is it possible to do so?
In ChildClass you can do something like this:
public partial class ChildClass : MainCLass
{
public override void Method1()
{
if(condition)
{
base.Method1();
return;
}
//YOUR LOGIC
}
}
EXAMPLE
public class A
{
public virtual void MethodA()
{
Console.WriteLine("A:MethodA");
}
}
public class B : A
{
public bool CallBase { get; set; }
public B()
{
CallBase = false;
}
public override void MethodA()
{
if (CallBase)
{
base.MethodA();
return;;
}
Console.WriteLine("B:MethodA");
}
}
class Program
{
static void Main(string[] args)
{
A a = new A();
B b = new B();
a.MethodA();
b.MethodA();
b.CallBase = true;
b.MethodA();
A c = new B();
c.MethodA();
A d = new B(true);
d.MethodA();
Console.ReadKey();
}
}
Output
A:MethodA
B:MethodA
A:MethodA
B:MethodA
A:MethodA

Databuilder pattern issue

I am playing with data builder pattern, and I am failing to understand some behaviours.
I wrote this simplified version of what I am trying to achieve below
public abstract class DataBuilderParent
{
private MyParent myParent;
protected void SetDataBuilder(MyParent myParent)
{
this.myParent = myParent;
}
public DataBuilderParent WithId(int id)
{
myParent.Id = id;
return this;
}
}
public class DataBuilderChild : DataBuilderParent
{
private readonly MyChild myChild = new MyChild();
public DataBuilderChild()
{
base.SetDataBuilder(myChild);
}
public DataBuilderChild WithDescription(string description)
{
myChild.Description = description;
return this;
}
private MyChild Build()
{
return myChild;
}
public static implicit operator MyChild(DataBuilderChild dataBuilder)
{
return dataBuilder.Build();
}
}
public class MyParent
{
public int Id { get; set; }
}
public class MyChild : MyParent
{
public string Description { get; set; }
}
Usage of the code above
internal class Program
{
private static void Main(string[] args)
{
MyChild child = new DataBuilderChild().WithDescription("");
}
}
Now it will create the child for me, also the intellisense shows up that I can do this new DataBuilderChild().WithId(1).WithDescription("");
however when I try to build it fails. I do not understand why I am not able to access this method ? it is public and its visible by the intellisense.
Can anybody explain how to make it work please?
Thank you
EDIT
The error message is: Error 1 Cannot implicitly convert type 'TestProgram.Program.DataBuilderParent' to 'TestProgram.Program.MyChild' C:\Apps\TestProgram\Program.cs 44 29 TestProgram
I just refactored my answer from the comments.
public class MyParent
{
public int Id { get; set; }
}
public class MyChild : MyParent
{
public string Description { get; set; }
}
Make the WithDescription method in the DataBuilderParent class as abstract.
public abstract class DataBuilderParent
{
private MyParent myParent;
protected void SetDataBuilder(MyParent myParent)
{
this.myParent = myParent;
}
public DataBuilderParent WithId(int id)
{
myParent.Id = id;
return this;
}
public abstract DataBuilderParent WithDescription(string description);
private MyChild BuildAsChild()
{
return myParent as MyChild;
}
private MyParent Build()
{
return myParent;
}
public static implicit operator MyChild(DataBuilderParent dataBuilder)
{
return dataBuilder.BuildAsChild();
}
public static implicit operator MyParent(DataBuilderParent dataBuilder)
{
return dataBuilder.Build();
}
}
Then the DataBuilderChild
public class DataBuilderChild : DataBuilderParent
{
private readonly MyChild myChild = new MyChild();
public DataBuilderChild()
{
base.SetDataBuilder(myChild);
}
public override DataBuilderParent WithDescription(string description)
{
myChild.Description = description;
return this;
}
private MyChild Build()
{
return myChild;
}
public static implicit operator MyChild(DataBuilderChild dataBuilder)
{
return dataBuilder.Build();
}
}
You would then build like this
class Program
{
static void Main(string[] args)
{
var childBuilder = new DataBuilderChild().WithId(1).WithDescription("Child");
MyParent parent = childBuilder;
MyChild child = childBuilder;
Console.WriteLine(#"Parent With Id {0}", parent.Id);
Console.WriteLine(#"Child With Id {0} and Desciprtion - {1}", child.Id, child.Description);
Console.ReadKey();
}
}
The return value of WithId is DataBuilderParent, which does not define the method WithDescription; this is only defined in the derived class DataBuilderChild. Apparently you aim at having some Named Constructor idiom on a class hierarchy, which cannot be implemented this way.
Furthermore, DataBuilderParent does not define a cast operator, neither to MyChild nor to MyParent, whereas DataBuilderChild defeines a cast operator to MyChild, as stated in the error message.

Override only Get accessor

I got an abstract class :
abstract class ClassBase
{
public abstract string Test { get; }
}
I want to derive it and by the way add a set accesor
class ClassDerive : ClassBase
{
string _s;
public override string Test
{
get { return _s; }
set { _s = value; }
}
}
I can't do that because i may not override set
class ClassDerive2 : ClassBase
{
string _s;
public string Test
{
override get { return _s; }
set { _s = value; }
}
}
Syntax error
class ClassDerive3 : ClassBase
{
string _s;
public override string ClassBase.Test
{
get { return _s; }
}
public string Test
{
set { _s = value; }
}
}
Syntax error
Any Idea ???
thx
You cannot do exactly what you want to do but here is a workaround:
abstract class ClassBase
{
public abstract String Test { get; }
}
class ClassDerive : ClassBase
{
string _s;
public override string Test
{
get { return _s; }
}
public void SetTest(String test)
{
this._s = test;
}
}
This will make Test only settable in ClassDerived via the public SetTest method. I know this is not as clean as using the property's setter but it is about as good as it's going to get.
If at first you have defined a read-only property in a type, you can't later change it to a read/write property in a derived class. That's simply how .NET works, and can't be changed.
If, on the other hand, you define an interface with a read-only property, you can later implement that interface in a class with a writable property.
If you'd like to share what you are trying to achieve, perhaps we can come up with a design that works and can compile :)
Another way:
abstract class ClassBase
{
public abstract string Test { get; }
}
class ClassDerive : ClassBase
{
string _s;
protected void setTest(string s)
{
_s = s;
}
public override string Test
{
get { return _s; }
}
}
class ClassDerive2 : ClassDerive
{
public new string Test
{
get { return base.Test; }
set { setTest(value); }
}
}
class Program
{
static void Main(string[] args)
{
var cd2 = new ClassDerive2();
cd2.Test = "asdf";
Console.WriteLine(cd2.Test);
}
}
My first thought was also to implement it as an interface. If this fits in with your design, the following code will work:
public interface TestInterface
{
string TestProperty { get; }
}
public class TestClass : TestInterface
{
public string TestProperty
{
get { return "test"; }
set { string t = value; }
}
}
No you cant, sorry. It is by design, so it's the law.

Object Oriented Approach for C#

I am exploring this and see if this one make sense. For instance I have 2 abstract objects called: Customer and Tender. The relationship is that one Customer can have many Tenders.
How can I achieve the following on the TestClient app:
customer.InTender[0].ID = ???
What method to handle to handle this? Do I need to pass CustomerID into Customer constructor to achieve this or ... ?
If I want to get all tenders for that particular customer should I do this:
customer.InTender.Get()
How do I differentiate between All Tender VS All Customer Tender (point 3). I guess it will be like this. One with ID of Customer and the other one without?
inTender.Get()
public abstract class Customer
{
protected Int64 id;
protected string name;
protected ArrayList tender;
public abstract ArrayList Tender
{
get;
set;
}
public abstract Int64 ID
{
get;
set;
}
public abstract string Name
{
get;
set;
}
public abstract bool Update();
public abstract bool Add();
public abstract bool Delete();
}
public class CorporateCustomer : Customer
{
public CorporateCustomer ()
{}
public override ArrayList Tender
{
get
{
return tender
}
set
{
tender = value;
}
}
public override Int64 ID
{
get
{
return id;
}
set
{
id = value;
}
}
public override string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public override bool Update()
{
return true;
}
public override bool Add()
{
return true;
}
public override bool Delete()
{
return true;
}
}
public abstract class Tender
{
protected Int64 id;
protected string name;
public abstract bool Update();
public abstract bool Add();
public abstract bool Delete();
}
public class InTender : Tender
{
public InTender ()
{}
public override Int64 ID
{
get
{
return id;
}
set
{
id = value;
}
}
public override string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public override bool Update()
{
return true;
}
public override bool Add()
{
return true;
}
public override bool Delete()
{
return true;
}
}
1) Don't use ArrayList, it was depreciated as of .net 2.0. You should use List, IList, or Dictionary.
Also, Customer sure seems like concrete type. Are you going to have multiple Customer classes that all inherit from it? If not, drop the Abstract. Same goes for your other classes.
2) Look up Repository objects and LazyLoading. Davy Bryon has a good series on building your own DAL. http://davybrion.com/blog/2009/08/build-your-own-data-access-layer-lazy-loading/
But either the customer should have all of the Tenders right away, or you should have a service that gets them for you. I'm not in favor of having Entities know about their persistence.
Anyway, the general approach is to have a separate Repository class that has the methods needed to get the data you need.
public class CustomerRepository
{
public List<Customer> GetAllCustomers() { .... }
public List<Tenders> GetTendersForCustomer(Customer customer) { .... }
}
I think a standard Tender class and a standard Customer class with a property List < Tender > should suffice. I don't see why you need the abstract classes and the inheritance.
class Tender {}
class Customer {
List < Tender > tenders; // would be null if customer has no tenders
....
}

Categories