Domanda

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;
            ...
È stato utile?

Soluzione 2

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.

Altri suggerimenti

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();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top