Reputation: 2189
I've searched for similar questions/problems on here and can't seem to find a solution that fits.
I currently have a class that it's constructor has one parameter which in turn calls a method which does not have any parameters but instantiates two objects. In the method, DoWork(), the requirements have changed, so I will need to handle other classes/objects, e.g. Building, Vehicle, etc. I am seeking advice on what would one recommend to take in these other objects, e.g. interfaces, generics, etc?
public class Project
{
public Person Person { get; set; } // will need to handle other classes as well
public String Task { get; set; }
// ctor
public Project(string task)
{
Task = task;
DoWork(); // should I handle this method here?
}
// current method
private void DoWork()
{
var work = new Work(this.Task);
Person = new Person(); // this instance of Person could be other objects as noted
Person.Job = work.Assignment;
Person.Site = work.Site;
...
Upvotes: 0
Views: 47
Reputation: 2111
If you want to retain the current structure and simply use a generic type instead of always creating a Person
, a very straightforward refactoring looks something like this.
Create an abstract base class for the resource (a person, building, vehicle) required for a project.
public abstract class Resource
{
public virtual Assignment Job { get; set; }
public virtual Site Site { get; set; }
}
Create your concrete classes.
public class Person : Resource
{
public Person()
{
}
}
public class Building : Resource
{
public Building()
{
}
}
Now you can make your Project
class accept a generic type T
instead of Person
. In this example, T must be some derived class of Resource
and must support a parameterless constructor.
public class Project<T> where T : Resource, new()
{
public T Resource { get; set; } // will need to handle other classes as well
public String Task { get; set; }
// ctor
public Project(String task)
{
Task = task;
}
// current method
public void DoWork()
{
var work = new Work(this.Task);
Resource resource = new T(); // this instance of Person could be other objects as noted
resource.Job = work.Assignment;
resource.Site = work.Site;
// ...
}
}
You create your projects and do work like this.
Project<Person> personProject = new Project<Person>("MyTask");
personProject.DoWork();
Project<Building> buildingProject = new Project<Building>("MyBuildingTask");
buildingProject.DoWork();
You should not call DoWork
from the constructor as shown in your code sample. Create the instance first, then call the method.
Upvotes: 1
Reputation: 2986
If your classes Person, Building, Vehicle etc. shares some behavior, and the DoWork
method only uses this behavior, polymorphism (either abstract class or interface) would be the best solution.
public MyData Data { get; set; }
void DoWork() {
Data.DoStuff();
}
In the case it wouldn't work, you can overload your DoWork
method to do different stuff based on the instance, but this would require getting the instance as a parameter.
void DoWork(Person p) {
...
}
void DoWork(Building b) {
...
}
Otherwise, you can either use generics or polymorph on the Object class (and in both cases, deal with unwanted/unexpected types).
if (obj is Person)
...
else if (obj is Building)
...
else
throw new Exception();
Upvotes: 2