Extending a base class method - c#

I am new to C# and am trying to understand basic concepts. Thank you in advance for your help. I have some sample classes below (typed in this window so there may be some errors)and have two questions:
Is it possible to Call a derived class method that executes the code in the base class method with the same name, then executes the code in the derived class method? Every derived class will need to perform the base class code for the RunCheck then do specialized code specific to its class. I could name RunCheck() something else in the base class and then call it when I call the RunCheck() of the derived class but then I have to remember to call it on the RunCheck() in the derived class.
In the Program.cs I want to output all fields with a blank value if it is on a field that is not in the derived class I pass in. What would I pass in?
Here is my code:
class baseCheck
{
public DateTime StartTime { get; set; }
public DateTime LastRun { get; set; }
public int Runs { get; set; }
//Others
public void RunCheck()
{
if (Started != null)
started = DateTime.Now;
LastRun = DateTime.Now;
Runs++;
}
}
class FileCheck : baseCheck
{
public string FileName { get; set; }
public void RunCheck()
{
//I want all the code in the base class to run plus
//any code I put here when calling this class method
}
}
class DirectoryCheck : baseCheck
{
public string DirectoryName { get; set; }
public void RunCheck()
{
//I want all the code in the base class to run plus
//any code I put here when calling this class method
}
}
//Program.cs
static void Main()
{
//Create derived class - either DirectoryCheck or FileCheck
//depending on what the user chooses.
if (Console.ReadLine()=="F")
{
FileCheck c = new FileCheck();
}
else
{
DirectoryCheck c = new DirectoryCheck();
}
PrintOutput(c);
}
private void PrintOut(What do I put here?)
{
Console.WriteLine("Started: {0}",f.StartTime)
Console.WriteLine("Directory: {0}", f.DirectoryName)
Console.WriteLine("File: {0}", f.FileName}
}

Just call base.RunCheck() in your DirectoryCheck class:
public class DirectoryCheck : baseCheck
{
public string DirectoryName { get; set; }
public void RunCheck()
{
//I want all the code in the base class to run plus
//any code I put here when calling this class method
base.RunCheck();
Console.WriteLine("From DirectoryCheck");
}
}
Also with your current implementation you are hiding the base class RunCheck() method - you should really override it - this changes the method signature in the base class to
public virtual void RunCheck()
and in the derived classes to
public override void RunCheck()
I suspect what you really want though is something like the Non Virtual interface pattern (NVI) - Expose a protected virtual method in your base class, that child classes can override, but have a public method on the base class that is actually calling that method internally - this approach allows you to extend what you are doing before and after that call.
In your example this would look like this:
class BaseCheck
{
private DateTime Started { get; set; }
public DateTime StartTime { get; set; }
public DateTime LastRun { get; set; }
public int Runs { get; set; }
//Others
public void RunCheck()
{
if (Started != null)
Started = DateTime.Now;
LastRun = DateTime.Now;
Runs++;
CoreRun();
}
protected virtual void CoreRun()
{
}
}
public class DirectoryCheck : BaseCheck
{
public string DirectoryName { get; set; }
protected override void CoreRun()
{
//I want all the code in the base class to run plus
//any code I put here when calling this class method
Console.WriteLine("From DirectoryCheck");
}
}

In a derived class, you can call the method in the base class using:
public override void RunCheck()
{
base.RunCheck();
// Followed by the implementation of the derived class
}
As mentioned in the comments, the base method will need to be declared as virtual to allow overriding:
public virtual void RunCheck() { ... }
For your PrintOut() method, there is no magic way, but you could have it take the base class as a parameter, and then test for the type.
private void PrintOut(baseCheck f)
{
Console.WriteLine("Started: {0}", f.StartTime)
Console.WriteLine("Directory: {0}", f.DirectoryName)
if (check is FileCheck)
{
Console.WriteLine("File: {0}", ((FileCheck)f).FileName}
}
}
Or you could use overloads:
private void PrintOut(baseCheck f)
{
Console.WriteLine("Started: {0}", f.StartTime)
Console.WriteLine("Directory: {0}", f.DirectoryName)
}
private void PrintOut(FileCheck f)
{
PrintOut((baseCheck)f);
Console.WriteLine("File: {0}", ((FileCheck)f).FileName}
}
Or you could have your PrintOut method part of your class (maybe even use the existing ToString() method) and override it as required.

Related

Calling generic method with generic collection

I'm am just getting started with generics, and am confused by how to implement the following scenario.
This is my base class:
public abstract class UnclaimedProperty
{
public abstract string Key { get; }
public virtual void Process() { }
public virtual void Process(string FileName) { }
abstract public void WriteReport<T>(List<T> PropertyRecords, string FileName);
}
In my implementations I would like to pass a concrete list to the override. something like:
public class PennUnclaimed : UnclaimedProperty
{
public override void Process(string FileName)
{
var reportDollarRecords = new List<PennUnclaimed>();
//add items here
WriteReport(reportDollarRecords, "PennCash");
}
public override void WriteReport(List<UnclaimedProperty> PropertyRecords, string FileName)
{
//write report here
}
}
I get error:
'PennUnclaimed' does not implement inherited abstract member
'UnclaimedProperty.WriteReport<T>(List<T>, string)'
What would be the correct way to implement this?
Based on your comments, consider making the abstract class generic.
public abstract class UnclaimedProperty<T> where T : UnclaimedProperty<T> {
public abstract string Key { get; }
public virtual void Process() { }
public virtual void Process(string FileName) { }
abstract public void WriteReport(List<T> PropertyRecords, string FileName);
}
That way the implementation would look like this
public class PennUnclaimed : UnclaimedProperty<PennUnclaimed> {
public override void Process(string FileName) {
var reportDollarRecords = new List<PennUnclaimed>();
//add items here
WriteReport(reportDollarRecords, "PennCash");
}
public override void WriteReport(List<PennUnclaimed> PropertyRecords, string FileName) {
//write report here
}
public override string Key {
get {
return string.Empty; //TODO:return key
}
}
}
The constraint on the abstract class for the generic argument will allow it to be the type of the current class being implemented.

C# Resolving Base Class to Correct Repository Method Call Based on Implemented Type

In our current project, we have an abstract base user class that is implemented by multiple other user types. We have a comparison class that can compare any of these types and then needs to call a correct update api based on the implemented type. I am trying to avoid bringing an if(typeof(User)) logic tree into the code and was hoping to figure out some way to solve the issue with method overloading. Are there any design patterns that can help solve this issue with some type of interface that can be dependency injected? Here is a basic code example
using System;
using System.Collections.Generic;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
List<BaseUser> TestUsers = new List<BaseUser>();
TestUsers.Add(new UserA() { Email = "test1#test.com", Location = "New York, NY" });
TestUsers.Add(new UserB() { Email = "test2#test.com", State = "TN" });
foreach (var user in TestUsers)
{
//need to invoke the correct Print repo method based on the actual user type, possible interface?
}
Console.Read();
}
}
public abstract class BaseUser
{
public string Email { get; set; }
}
public class UserA : BaseUser
{
public string Location { get; set; }
}
public class UserB : BaseUser
{
public string State { get; set; }
}
public class UserARepo
{
void Print(UserA user)
{
Console.Write($"User A Saved {user.Email}, {user.Location}");
}
}
public class UserBRepo
{
void Print(UserB user)
{
Console.Write($"User B Saved {user.Email}, {user.State}");
}
}
}
If the Print methods only need the Email and Location/State properties of the objects, then change their signature to accept only these two strings.
I would add a common property to the abstract class, which returns the needed property in the User* classes:
namespace ConsoleApplication5
{
public abstract class BaseUser
{
public string Email { get; set; }
public string OtherLocation { get; set;}
}
public class UserA : BaseUser
{
public string Location { get; set; }
public string OtherLocation {
get
{
return this.Location;
}
set
{
this.Location = value;
}
}
}
public class UserB : BaseUser
{
public string State { get; set; }
public string OtherLocation {
get
{
return this.State;
}
set
{
this.State = value;
}
}
}
public class UserARepo
{
void Print(BaseUser user)
{
Console.Write($"User A Saved {user.Email}, {user.OtherLocation}");
}
}
public class UserBRepo
{
void Print(BaseUser user)
{
Console.Write($"User B Saved {user.Email}, {user.OtherLocation}");
}
}
}
Hopefully I'm understanding the problem correctly - but if each of those UserTypes needs an update API or Print Repo method, put them as abstract methods in the class:
public abstract class BaseUser
{
public string Email { get; set; }
public abstract void PrintRepo();
}
Basically, it's just a question of: what functionality is required of the subclasses if they want to implement your base class? They have to handle Update requests? Then put an abstract declaration in the abstract class that says, "Hey, if you inherit from me, you have to include an Update function."
Then your main function becomes something like:
foreach (var user in TestUsers)
{
user.PrintRepo();
}

What is an appropriate way to change property accessors on sub classes whilst maintaining polymorphism?

I have a few classes that inherit from a base class for which I wish to change the implementation of a property and method. I also require the base class and all sub classes to be be polymorphic, so I can later create a collection of any type that implements a particular interface.
When i create instances of my classes that implement an interface, I want to use properties and methods on that class (implemented by the interface), not the base class.
This is my simplified implementation of the issue that provides the desired output but does have a code smell...
class Program
{
static void Main(string[] args)
{
IGrid one = new TextField();
IGrid two = new SelectList();
one.Click();
two.Click();
Console.WriteLine(one.Text);
Console.WriteLine(two.Text);
Console.ReadLine();
}
}
public interface IGrid {
string Text { get; set; }
void Click();
}
public class Control : IGrid {
public string Text {
get { return "Hello Control!"; }
set { }
}
public virtual void Click() {
Console.WriteLine("In the Control!");
}
}
public class SelectList : Control, IGrid {
public int Number { get; set; }
public new string Text {
get {
return "Hello Select!";
}
set { Number = int.Parse(value); }
}
public override void Click() {
Console.WriteLine("In the Select!");
}
}
public class TextField : Control, IGrid {
public int Number { get; set; }
public new string Text {
get {
return "Hello TextField!";
}
set { Number = int.Parse(value); }
}
public override void Click()
{
Console.WriteLine("In the TextField!");
}
}
This works but feels a little messy having an empty set in the Control class.
Is there a cleaner approach to this type of problem without compromising on specific property implementations on sub classes?
Many thanks,
Okay, so first thing is first, you should not be changing another property when you set a property (like you are doing to Number from Text). This is a huge code smell because it is a side effect. You should always deal directly with the properties that you intend to.
public class SelectList : Control, IGrid {
public int Number { get; set; }
public new string Text {
get {
return "Hello Select!";
}
// This is bad, someone after you may not know that this has a side effect
set { Number = int.Parse(value); }
}
}
Second, a property can be virtual just like a method, so marking your Text property as virtual and overridding in a derived class will make polymorphism work the way it is intended. "Hiding" via the new keyword would require you to cast your interface its specific class in order to get that classes implementation.
public class Control : IGrid
{
public virtual string Text
{
get { return "Hello Control!"; }
}
public virtual void Click()
{
Console.WriteLine("In the Control!");
}
}
public class SelectList : Control, IGrid
{
public int Number { get; set; }
public override string Text
{
get
{
return "Hello Select!";
}
}
public override void Click()
{
Console.WriteLine("In the Select!");
}
}
Third, you do not have to have a setter on the interface. You could just have a getter and only need to implement that.
public interface IGrid
{
string Text { get; }
void Click();
}
Finally, if you are ALWAYS going to override a method or property and NEVER going to create the base class directly (with a new) then you should consider using an abstract class if you have shared implementation (EG at least one method or property you do not change) or don't bother with the base class because you are not using any of the code anyways.
// Abstract class
public abstract class Control : IGrid
{
// Property that is not overridden but is shared
public int Number { get; set; }
public abstract string Text
{
get;
}
public abstract void Click();
}
public class SelectList : Control
{
// Don't need the Number property here, base class has it
public override string Text
{
get
{
return "Hello Select!";
}
}
public override void Click()
{
Console.WriteLine("In the Select!");
}
}
// Need everything in this class, but if it is all different anyways
// then base class is kind of a waste
public class TextField : IGrid
{
public int Number { get; set; }
public string Text
{
get
{
return "Hello TextField!";
}
}
public void Click()
{
Console.WriteLine("In the TextField!");
}
}

DRY principle when working with multiple method signatures

With the DRY principle in mind, how would you tackle almost identical methods (with different signatures) that work with an IEnumerable. I.e. one signature works with a specific type parameter. My question extends to the calling of private methods, and their multiple signatures.
I don't want to have two methods with identical logic - If something changes then I have to change both sets of logic. The calling of the private methods for example, how can I make the private method accept either type of IEnumerable
public class Person
{
public string Name {get; set;}
public string Age {get; set;}
}
public class SupremeBeing : Person
{
public string Power {get; set;}
}
public class Payroll
{
public void DoSomething(IEnumerable<Person> peopleIn)
{
// Do this with peopleIn
// Do that with peopleIn
// Call private method passing in peopleIn (which also has 2 signatures)
}
public void DoSomething(IEnumerable<SupremeBeing> peopleIn)
{
// Do this with peopleIn
// Do that with peopleIn
// Call private method passing in peopleIn (which also has 2 signatures)
}
}
It looks to me like what you want is more abstraction on the Payroll Class
public abstract class PayrollBase<T> where T : Person
{
public void DoSomething(IEnumerable<T> peopleIn)
{
// Do this with peopleIn
// Do that with peopleIn
this.InternalLogic(peopleIn);
}
protected virtual InternalLogic(IEnumerable<T> peopleIn)
{
// do something super special
}
}
You would then implement this for your specific types
public PersonPayroll : PayrollBase<Person>
{
protected override InternalLogic(IEnumerable<Person> peopleIn)
{ ... }
}
public SupremeBeingPayroll : PayrollBase<SupremeBeing>
{
protected override InternalLogic(IEnumerable<SupremeBeing> peopleIn)
{ ... }
}
You would then use some form of factory class to instantiate the right "Payroll" for the list of people you're dealing with.
The object oriented approach would be to make the classes handle their differences themselves. You can for example use virtual methods to have one implementation for each class.
When you can treat every object as a Person object regardless of the actual type, then you only need one set of methods to handle the payroll, and you wouldn't need to call it with separate lists for each class, you can put them all in the same list and call the method.
Example:
public class Person {
public string Name {get; set;}
public string Age {get; set;}
virtual public int Salary { get { return 1000 + Age * 10; } }
override public string ToString() {
return Name + "(" + Age + ")";
}
}
public class SupremeBeing : Person {
public string Power {get; set;}
override public int Salary { get { return 5000 + Age * 7; } }
override public string ToString() {
return Power + " " + Name;
}
}
public class Payroll {
public void DoSomething(IEnumerable<Person> peopleIn) {
foreach (Person p in peopleIn) {
Console.log("{0} earns {1}", p, p.Salary);
}
}
}
One option is to call the first method from the second:
public void DoSomething(IEnumerable<SupremeBeing> peopleIn)
{
this.DoSomething(peopleIn.Cast<Person>());
// do SupremeBeing specific stuff
}
Another option is to have a private method which does all the Person stuff.
public void DoSomething(IEnumerable<SupremeBeing> peopleIn)
{
this.DoSomethingWithPersons(peopleIn);
}
public void DoSomething(IEnumerable<Person> peopleIn)
{
this.DoSomethingWithPersons(peopleIn);
}
private void DoSomethingWithPersons(IEnumerable<Person> peopleIn)
{
// do stuff
}
Subtle differences between the two options without more information it's hard to know which would be better.
I don't understand your problem. You could create a generic method which does your generic stuff and then create a method which could be overridden for your special stuff.
Like:
class Something
{
protected virtual void DoSomethingSpecial<TYPE>(TYPE item)
{
}
public void DoSomethingy<TYPE>(IEnumerable<TYPE> items)
{
foreach(TYPE item in items)
{
// do whatever you have to do for every type
// do whatever you have to do in special
this.DoSomethingSpecial(item)
}
}
}
Code not tested just typed.
And then create one class for every special case. In these classes you just override DoSomethingSpecial for every type and you're done.
You could just have the Payroll class sort out the different types of Persons after it has run all the common operations and forward people to the appropriate extended methods.
interface IPerson {
string Name { get; set; }
string Age { get; set; }
}
public class Person : IPerson {
public string Name { get; set; }
public string Age { get; set; }
}
public class SupremeBeing : Person
{
public string Power { get; set; }
}
public class Payroll
{
public void DoSomething(IEnumerable<IPerson> peopleIn)
{
//..everyone does this and that
IEnumerable<Person> NormalPeople = peopleIn.OfType<Person>();
if (NormalPeople.Count() > 0) DoSomethingNormalSpecific(NormalPeople);
IEnumerable<SupremeBeing> SupremeBeings = peopleIn.OfType<SupremeBeing>();
if (SupremeBeings.Count() > 0) DoSomethingSupremeSpecific(SupremeBeings);
}
public void DoSomethingNormalSpecific(IEnumerable<Person> normalPeopleIn)
{
// just normal people
}
public void DoSomethingSupremeSpecific(IEnumerable<SupremeBeing> supremeBeingsIn)
{
// just Supreme Beings
}
}

How Can I Accept a Generic Class and Use Its Properties / Methods

I want to create a class that could hold any of a number of same type of classes. For example lets says I have a base class like follows:
public class BaseClass
{
public string MyBaseString
{
get;
set;
}
}
And then I have a few derived classes like this:
public class DerivedClass : BaseClass
{
public MyDerivedClassString
{
get;
set;
}
}
public class DerivedClass2 : BaseClass
{
public MyDerivedClass2String
{
get;
set;
}
}
Now I would like a class that accepts one of these implementations and does stuff with it. Here is the only thing I can think of, but there must be a better way:
public class ClassA
{
public object MyClass
{
get;
set;
}
public ClassA (object myClass)
{
MyClass = myClass;
if (object is BaseClass)
{
//do something
}
else if (object is DerivedClass)
{
//do something specific to derived class
}
else if (object is DerivedClass2)
{
//do something specific to derived class 2
}
}
}
CLARIFICATION: The specific goal I am trying to accomplish is to use ClassA as a container class for various implementations of the BaseClass. The business goal I am trying to accomplish is to create a Legend object which might use multiple color schemes (i.e. a Mono Color Ramp, Multi Color Ramp, etc). So I would like the Legend class to contain the ColorScheme that is being used, but still have access to that color scheme's unique properties for modification later on.
CLARIFICATION 2 Based on the wide array of responses I got, I thought I'd provide an exact replication of what I'm trying to do:
public class BaseColorScheme
{
List<Color> _colors = new List<Color>();
public List<Color> Colors
{
get
{
return _colors;
}
set
{
_colors = value;
}
}
}
public class SingleColorScheme : BaseColorScheme
{
public Color MidColor
{
get;
set;
}
public SingleColorScheme( Color midColor, int numberOfClassifications )
{
Colors = CreateMonoColorRamp( midColor, numberOfClassifications );
}
}
public class MultiColorScheme : BaseColorScheme
{
public Color StartColor
{
get;
set;
}
public Color EndColor
{
get;
set;
}
public Color MidColor
{
get;
set;
}
public MultiColorScheme( Color startColor, Color endColor, Color midColor )
{
StartColor = startColor;
EndColor = endColor;
MidColor = midColor;
Colors = //do something to define multi color scheme
}
}
Then I would have a Legend Class that would be something like
public class Legend
{
public object ColorScheme
{ get; set; }
public Guid LegendId
{ get; set; }
public Legend(object colorScheme)
{
ColorScheme = colorScheme;
}
}
Finally I might have a form that sits on top of the legend that displays the properties of the various color schemes based on which type of color scheme it is. Hopefully that helps clarify a bit.
public class ClassA<T> where T : BaseClass
{
public T MyClass { get; set; }
public ClassA(T myClass) { MyClass = myClass; }
}
Beyond that, define the common interface of the class hierarchy either as an interface or as methods (concrete, abstract, or virtual) within the base class. Then you can be assured all derived classes have such method / properties and can use them within your generic wrapper.
Instead of letting ClassA perform whatever needs to be done, you can use polymorphism and let the classes do it to themselves.
Simply declare a virtual method in the base class, have it do whatever you need it do so, and then override this method in the subclasses. In the method in ClassA, you just need to call that method on the object you receive as a parameter - without having to care about the specific type.
If you need to access different properties based on which derived class is passed something like this should help:
public class ClassA<T> where T : BaseClass
{
public T MyClass { get; set; }
public ClassA(T myClass) { MyClass = myClass; }
public void DoStuffToMyClass()
{
if(MyClass is BaseClass)
{ // do base class stuff }
else if(Myclass is DerivedClass)
{ // do DerivedClass stuff }
else if(MyClass is DerivedClass2)
{ // do DerivedClass2 stuff }
}
}
This gives you the type saftey to ensure you at least have the BaseClass object, and possibly a derived class.
The answer is polymorphism, let the object do it themselves.
public class BaseClass
{
public string MyString { get; set; }
public virtual string DoIt()
{
return "I'm Base Class";
}
}
public class DerivedClassA
{
public override string DoIt()
{
return "I'm Derived Class A";
}
}
public class DerivedClassB
{
public override string DoIt()
{
return "I'm Derived Class B";
}
}
....
public ClassA (BaseClass myClass)
{
MyClass = myClass;
MyClass.DoIt();
}
.....
ClassA x1 = ClassA(new BaseClass()) // calls BaseClass.DoIt()
ClassA x2 = ClassA(new DerivedClassA()) // calls DerivedClassA.DoIt()
ClassA x3 = ClassA(new DerivedClassB()) // calls DerivedClassB.DoIt()
whenever you catch yourself acting differently based on the run-time type of the object, you are dealing with code that breaks OO principles, i.e. a class that does not respect the base class contract.
Can you use virtual methods?
public abstract class BaseClass
{
public abstract void DoStuff();
}
public class DerivedClass1 : BaseClass
{
public override void DoStuff()
{
...
}
}
public class DerivedClass2 : BaseClass
{
public override void DoStuff()
{
...
}
}
Without generics:
public class ClassA
{
public BaseClass MyClass
{
get;
set;
}
public ClassA (BaseClass myClass)
{
MyClass = myClass;
myClass.DoStuff();
}
}
or with generics:
public class ClassA<T> where T : BaseClass
{
public T MyClass { get; set; }
public ClassA (T myClass)
{
MyClass = myClass;
myClass.DoStuff();
}
}
Keep it simple: polymorphism
Hopefully your objects have a common interface, something like:
class Base {
public virtual void DoSomething() { /* Default implementation */ }
}
class Derived1 : Base {
public override void DoSomething() { /* Implementation specific to this type */ }
}
class Derived2 : Base {
public override void DoSomething() { /* Another implementation specific to this type */ }
}
Or maybe they implement a common interface. So hopefully your consuming class can hold the most general representation of your inputs as possible and invoke code as such:
class Dependent {
public Dependent(Base instance) {
instance.DoSomething();
}
}
So your Dependent class doesn't really are whether it has a derived type or a base type.
Not quite as simple: visitor pattern
Sometimes polymorphism doesn't really work, which is particularly the case if you need to access the specific members of your derived classes, and those members aren't in the base class. Visitor pattern works well in this case, especially if you have a fixed, well-defined graph of objects.
public interface IVisitor<T> {
T Visit(Base x);
T Visit(Derived1 x);
T Visit(Derived2 x);
}
class Base {
public virtual T Accept<T>(IVisitor<T> visitor) { visitor.Visit(this); }
public string BaseString { get; set; }
}
class Derived1 : Base {
public override T Accept<T>(IVisitor<T> visitor) { visitor.Visit(this); }
public string Derived1String { get; set; }
}
class Derived2 : Base {
public override T Accept<T>(IVisitor<T> visitor) { visitor.Visit(this); }
public string Derived2String { get; set; }
}
So Derived1 and Derived2 have a different set of properties, and if you need to get to those properties without a runtime type-checking, implement a visitor:
class DefaultStringVisitor : IBaseVisitor<string> {
public string Visit(Base x) { return x.BaseString; }
public string Visit(Derived1 x) { return x.Derived1String; }
public string Visit(Derived2 x) { return x.Derived2String; }
}
class Dependent {
public Dependent(Base x) {
string whatever = x.Accept<string>(new DefaultStringVisitor());
}
}
So the visitor pattern gives you access to your derived object's members without a type-check. Its a somewhat inflexible pattern (i.e. need to know which objects to visit up front), but it might work for your needs.

Categories

Resources