Abstract method vs static method in Program class - c#

Say I've got a simple inheritance chain where Employee is the abstract base class and Checkout and Manager inherit from it in this purely illustrative console app. Now I want to have a method that will take in an object of type Manager or Checkout and return an integer amount of a bonus depending on the position in the company of the employee. I had some initial thoughts on doing this, and would like to know potential long-term deficits or gains from each approach if this console app were to one day grow up to be a data-driven web application.
Use an interface common to the inherited classes.
My base class looks like
abstract class Employee
{
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
and my derived classes implement an interface designed to print employee information to the console called IPrintable and only has one method to do so. Although this interface has nothing to do with giving bonuses I mocked up the following in the class with my Main method lives and the program runs fine.
static int GiveBonusesViaInterface(IPrintable i)
{
if (i is Checkout)
return 1000;
else
return 2000;
}
It seems to me that if I wanted to use an interface for this I should probably make another one specific to giving raises instead of riding the coattails on an already-implemented interface (but that's another question for another day).
Use a static method in the base class like
public static int GiveBonus(Employee e)
{
if (e is Manager)
return 2000;
else
return 1000;
}
Make an abstract method in the abstract base class and nave derived classes implement as they see fit
abstract class Employee
//fields and constructors
{
public abstract int GiveBonusesViaAbstractMethod(Employee e);
}
This seems to be the worst idea to me because there will have to be a method in each derived class that takes in a parameter of IPrintable or Employee type and in the Manager class we'd have to test if the employee is-a Manager.
Are 1-2 equally as scalable and managable for a long-term web application? Is option 3 really as bad as I made it out?

You're missing the traditional OO way of doing this:
abstract class Employee {
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public abstract int GetBonusAmount();
}
class Manager : Employee {
public override int GetBonusAmount() { return 2000; }
}
class Checkout : Employee {
public override int GetBonusAmount() { return 1000; }
}
Console.WriteLine(someEmployee.GetBonusAmount());

I think you really have already answered your own question.
my derived classes implement an interface designed to print employee information to the console called IPrintable and only has one method to do so. Although this interface has nothing to do with giving bonuses
[emphasis mine]
You already have an interface for this. It's called Employee. The idiomatic way to do to this is to implement a virtual method on your abstract class and override if necessary. The more idiomatic C# approach is to write a property and override it. Like so:
abstract class Employee {
public virtual int GetBonus()
{
return this.Bonus;
}
public virtual int Bonus { get; set; }
}
class Manager : Employee {
public override int Bonus
{
get { return 2000; }
}
}
class Checkout : Employee {
public override int Bonus
{
get { return 1000; }
}
}

Implement a GetBonus() method in both the subclasses. You should avoid doing "is instance of" checks altogether.

I think abstract works well :
abstract class Employee
{
public int EmployeeId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public abstract int GetVariableBonus();
}
class Manager {
public int GetVariableBonus(){
return 2000;
}
}
class Employee{
public int GetVariableBonus(){
return 1000;
}
}
Is that what you need ?

Related

Problem in class design with multiple base model

I have a base class for all the ENTITIES of my project which is inheriting from below model :
public class BaseModel
{
public int Id { get; set; }
public int CreatedDate { get; set; }
public override string ToString();
}
Now I have 1 another functionality which is common for so many modules and I want to keep BaseModel for that functionality and want it to be inherited from it.
Public class BaseNotice
{
// Common info related to notice which is use to send notice to employees in different scenarios
}
Now our every model is suppose to inherit from BaseModel so inheriting from BaseNotice will be multiple inheritance.
Now I cannot like below :
Public class BaseNotice : BaseModel
{
// Common info related to notice which is use to send notice to employees in different scenarios
}
Because I would like to control functionality related to Notice from BaseNotice model and for notice I would like to keep BaseNotice as base model.
But I am not getting how to avoid multiple inheritance here and so what would be the proper way to design this?
There is No need to Multiple Inheritance. you can do that in this way:
public class BaseModel
{
public int Id { get; set; }
public int CreatedDate { get; set; }
public override string ToString();
}
public interface IBaseNotice
{
// Base Notices Contracts should be placed here
}
Public class BaseNotice: IBaseNotice
{
// Common info related to notice which is use to send notice to employees in different scenarios
}
public class ModelX:BaseModel
{
public IBaseNotice Notice { get ; set; }
public ModelX(IBaseNotice baseNotice)
{
Notice = baseNotice;
}
}
Or you can use Second Generation of your BaseModel:
public class BaseModeNoticable:BaseModel
{
public IBaseNotice Notice { get ; set; }
public BaseModeNoticable(IBaseNotice baseNotice)
{
Notice = baseNotice;
}
}

c# on nested property change tracking

I have a generic class with a single argument that represents an Element of a third party DLL for the purpose of serialization of objects of T kind. What I would like to do is add a 'Dirty' map to my class and lazily trigger it whenever one of my Element's nested properties are changed.
Is it possible to when the property is accessed catch the request and identify what property is changing? That if a SET is being performed I can log that sub-property P is now dirty and needs to be saved? Or at least a single bit that indicates that SOMETHING has changed?
public class ResourceSerializer<T>
where T : Base, new()
{
T element;
Dictionary<String,Boolean> dirtyMap;
public T Element { get { return this.getElement(); } }
public Boolean IsDirty { get; private set; }
public ResourceSerializer()
{
dirtyMap = new Dictionary<string,bool>();
element = new T();
// code to reflect back upon T's Properties and build out the dirtyMap.
// I already can do this I just omitted it.
// in my Person example there would be keys: 'FirstName', 'LastName', 'Age', 'Gender', 'PrimaryAddress'
}
// how can I call this programmatically?
void flagDirty(String property)
{
dirtyMap[property] = true;
this.IsDirty = true;
}
T getElement()
{
// In case I need to do a thing before returning the element.
// Not relevant to the question at hand.
return this.element;
}
}
a somewhat advanced example of 'Base'. You can see how I need to recurse my actions as not everything is a primitive. I have a manager level class that logs all of these ResourceSerializer objects.
public class Base
{
public Base()
{
}
}
public enum gender
{
Male,
Female,
Other,
Unspecified,
}
public class Address : Base
{
public String Street { get; set; }
public String State { get; set; }
public String Zip { get; set; }
public Address() : base()
{
}
}
public class Person : Base
{
public String FirstName { get; set; }
public String LastName { get; set; }
public Int16 Age { get; set; }
public gender Gender { get; set; }
public Address PrimaryAddress { get; set; }
public Person() : base()
{
}
}
public class Patient : Person
{
public Person PrimaryContact { get; set; }
public Patient() : base()
{
}
}
and a small class i would turn into a test method later..
public class DoThing
{
public DoThing()
{
ResourceSerializer<Person> person = new ResourceSerializer<Person>();
person.Element.Age = 13; // catch this and mark 'Age' as dirty.
}
}
Without a custom setter no, there's nothing to do that.
The usual pattern for what you're trying to do is implement the INotifyPropertyChanged interface, that interface is precisely created for classes (or structs) which need to track and inform about changes on their properties.
If you're lazy as me, I would create an analyzer which at the beginning of my app scans all my classes which are tagged with an attribute and with all properties created as virtual, then using codedom I would create a new class which would inherit from the found class and it implements the INotifyPropertyChanged, then you can have a generic Factory which returns instances of these new classes when the type of the generic call is of a known registered type.
I've used this before for classes which I wanted to have remote properties, just tagged the class and my scan system rewrote the getter/setter to do the remote calls transparently, the concept at the end is the same.
It's a lot of work at the begining, but if you have a ton of classes it will be a lot less of code to write than implementing INotifyPropertyChanged on all your classes.

C#, abstract superclass implementing a concrete variable defined by the subclass?

I have a system that performs operations on lots of Things, these can be considered to be hardware devices accessible over a communication channel.
I use a manager construct that accepts tasks for single Things. Now, there are at least three types of Thing and they have slightly different properties associated with them. The manager must know about these extra properties as they are needed to perform any operation correctly (some Things must have their X foo'd instead of their Y etc...).
At the moment I have separate manager class for each type of thing. This causes a good deal of duplication as the Things are mostly similar.
It would be good if I could have an abstract manager that implements a good deal of the functionality and then each concrete implementation can supply the little extra bits.
Here is a greatly simplified example:
public abstract class ThingManager
{
private ConcurrentDictionary<Guid, ??ThingTask??> _ThingTaskQueue;
public virtual AddNewThingTask(<params>)
{
??ThingTask?? NewTask = new ??ThingTask??(<params>);
_ThingTaskQueue.Add(NewTask);
Monitor.Pulse(_NewDataToProcess);
}
/* Implemented by the concrete, will depend on the type of ??ThingTask?? */
public abstract GetSomeTaskParameterForAThing(Guid thingID)
}
public class ThingTask
{
public enum ThingOperation
{
Foo,
Bar
};
public String Name { get; set; };
public ThingType Type { get; set; };
public ThingOperation Operation { get; set; }
}
public class AdvancedThingTask
{
public enum ThingOperation
{
Foo,
Bar,
Baz
};
public String Name { get; set; };
public ThingType Type { get; set; };
public ThingOperation Operation { get; set; }
public Boolean EnableFrobber { get; set; }
}
As you can see I need some way, when defining the concrete ThingManager to have ??ThingTask?? be either a ThingTask or an AdvancedThingTask. It would then be up to the concrete to make use of the extra properties when implementing the abstract methods.
Using an interface for ??ThingTask?? wouldn't work because the properties would have to be declared in the interface and each one has different properties available.
I get the feeling I'm missing something very obvious as to how to do this cleanly, hopefully someone can help :)
use generics rather than a pure abstract class, someting along the lines of:
public abstract class ThingManager<T> where T : ThingTask
dependant on your full implementation I doubt if this will need to remain abstract
Is there any reason you don't make AdvancedThingTask a subclass of ThingTask?
public class ThingTask
{
public virtual string Name { get; set; }
public virtual ThingType Type { get; set; }
public virtual ThingOperation Operation { get; set; }
public virtual void DoThing() { /*Do something associated with ThingTask*/ }
}
public class AdvancedThingTask : ThingTask
{
public bool EnableFrobber { get; set; }
public override void DoThing() { /*Do something associated with AdvancedThingTask*/ }
}
The only problem I see with this is that ThingOperation will need to be declared outside of the classes so that it can have all the values, or some other solution that will enable classes to have values that aren't in the base declaration. That problem may be solved by putting what you want to do as virtual methods in the classes.
P.S. Why do your properties start with underscores? Usually that's reserved for private variables.

inheritance and roles

Let's use a quite plain example with employees and company(-ies).
public abstract class Employee
{
// bunch of its features
}
public sealed class SalesManager : Employee
{
}
public sealed class SEO : Employee
{
}
Employee can take different posts or play different roles. So using inheritance (maybe with factory patterns in addition) doesn't give such a flexibility for concrete employee instance to change its role.
What would you advice, unfortunately I haven't seen the kind of approaches yet. And I haven't met a book which lights up the problem.
Edit
Thank you guys! In my edit I wanted to ask one more thing. Using generic role is it possible to transfer such a BLL to DAL. I have heard that generics are not supported in Entity Framework??
Thanks!
Use a has-a relationship
public class Employee
{
public Role EmployeeRole { get; set; }
}
public enum Role
{
SalesManager,
SalesPerson
}
Or you can make Role a class to store additional information in addition to the name of their role.
public class Role
{
public string Name { get; set; }
public decimal BaseSalary { get; set; }
}
To illustrate #Aasmund Eldhuset's comment:
public abstract class Role
{
public string Name { get; set; }
public decimal BaseSalary { get; set; }
public abstract void PerformRole();
}
public class SalesPerson : Role
{
public void PerformRole()
{
// Do something
}
}
Running with the idea of using a class, you can make it generic:
abstract class EmployeeRole { }
or
interface EmployeeRole { }
And have different types inherit from this abstraction:
class CEO : EmployeeRole { }
class SalesMgr : EmployeeRole { }
class Employee<T> where T : EmployeeRole
{
}
Then have a generic Factory implementation:
public Employee<T> MakeEmployee<T>() where T : EmployeeRole
{
}

Abstract class in LINQ2SQL for sharing common methods

I'm having trouble trying to implement a shared method/property between two classes created by the linq2sql designer.
My two classes have two main properties (coming from the db model):
public partial class DirectorPoll
{
public bool Completed {get; set;}
public bool? Reopen { get; set; }
//more properties
}
public partial class StudentPoll
{
public bool Completed {get; set;}
public bool? Reopen { get; set; }
//more properties
}
Now for example I create an abstract class:
public abstract class GenericPoll
{
public abstract bool Completed { get; set; }
public abstract bool? Reopen { get; set; }
public bool CanEdit
{
get
{
if (Completed == false) return true;
if (Reopen.GetValueOrDefault(false) == false) return false;
return true;
}
}
}
Then
public partial class DirectorPoll : GenericPoll
public partial class StudentPoll: GenericPoll
But when I try to compile it says "Director does not implement inherited abstract member GenericPoll.Completed.get". But it is there. So I think I'm forced to put an override to the property automatically generated by the designer, but if I update the database later and recompile it will give me the same error.
I think I might be missing something here but I've tried different approaches with no success. ¿So what can I do here, besides implementing CanEdit in each of my partial classes? Thanks
It isn't implemented as an override, so it doesn't count. However, implicit interface implementations do count, so this works:
partial class DirectorPoll : IGenericPoll {}
partial class StudentPoll : IGenericPoll {}
public interface IGenericPoll
{
bool Completed { get; set; }
bool? Reopen { get; set; }
}
public static class GenericPoll {
public static bool CanEdit(this IGenericPoll instance)
{
return !instance.Completed || instance.Reopen.GetValueOrDefault();
}
}
One option: create an interface containing Completed and Reopen, make the classes implement the interface (via the manual bits of the partial classes), then write an extension method which extends that interface. I think that should work:
public interface IPoll
{
bool Completed {get; set;}
bool? Reopen { get; set; }
}
// Actual implementations are in the generated classes;
// no need to provide any actual code. We're just telling the compiler
// that we happen to have noticed the two classes implement the interface
public partial class DirectorPoll : IPoll {}
public partial class StudentPoll : IPoll {}
// Any common behaviour can go in here.
public static class PollExtensions
{
public static bool CanEdit(this IPoll poll)
{
return !poll.Completed || poll.Reopen.GetValueOrDefault(false);
}
}
Admittedly then it has to be a method rather than a property, as there's no such thing as an extension property, but that's not too much of a hardship.
(I believe my refactoring of your logic in CanEdit is correct. All those explicit trues and falses were doing my head in ;)

Categories