简体   繁体   中英

Class design and object references

Here is a very basic example of what I am trying to do. In reallity there are more relations but not something extreme or memory heavy.

public class ClassA : ISomething
{
    public double property { get; set; }
    ...
    public ClassB classb { get; set; }
}

public class ClassB : ISomething2
{
    public double Length { get; set; }
    ...
}

public class MyProject : BaseProject
{
    public IEnumerable<ISomething> ISomethings { get; set; }
    ...
    public IEnumerable<ISomething2> ISomethings2 { get; set; }
    ...
}

The issue here is that I have to keep a list of ISomethings2 and then classb property of ClassA to reference only an existing item in the ISomething2 list. The hard thing here is that:

  • Removing an item from ISomething2 should remove all references to it ( classb property of ClassA instances to be set to null)
  • Prevent other developers setting classb property to a non existing object in list or a new user created object.
  • Objects in ISomethings2 can exist without being referenced.

These classes are used for project description not database stuff. Like when you open a project file for an application. So changing a property in classB should be visible to all since it is the same object reference. Is there a pattern to achieve what I want without much coupling? Alternative designs/approaches are also welcome.

You need a Manager class, and add some behavior in your classes.

First is the ManagerClass

public class ManagerClass{
    public IEnumerable<ISomething> ISomethings { get; set; }
    public IEnumerable<ISomething2> ISomethings2 { get; set; }

    public void RemoveSomething2(ISomething2 something2){
        //iterate through ISomething and remove the ClassB reference
    }
}

ClassA accept ManagerClass constructor, revoke ClassB set property.

public class ClassA : ISomething
{
    public ClassA (ManagerClass managerClass){
        this.managerClass = managerClass;
    }

    public double Property { get; set; }

    private ManagerClass managerClass = null;
    public ManagerClass ManagerClass { get { return managerClass; } }

    private ClassB classB null;
    public ClassB ClassB { get{ return classB; } }

    public void SetClassB(ClassB classB){
        // check whether 
        if(classB != null && !ManagerClass.ISomethings.Any(k=> k==classB)){
            this.classB = classB;
        }
        // set null
        else if(classB == null){
            this.classB = null;
        }
        else {
            throw new Exception("not found");
        }
    }
}

Though I prefer a simplified version with relational model.

public class SomethingRelation{
    public ISomething something;
    public ISomething2 something2;
}

public class ManagerClass{
    public IEnumerable<ISomething> ISomethings { get; set; }
    public IEnumerable<ISomething2> ISomethings2 { get; set; }
    public IEnumerable<SomethingRelation> Relations { get; set; }

    public void RemoveSomething2(ISomething2 something2){
        //iterate through SomethingRelation and remove all the something2 reference
    }
}

Hmmm, personaly I would replace the ClassB object in ClassA with string ClassBId and just have the one list.

BUT! if you want to keep the structure you could make the project ISomething2 enumerable link to the ISomethign1 enumerable. ie

    public class MyProject 
    {     
        public IEnumerable<ISomething> ISomethings { get; set; }

        public IEnumerable<ISomething2> ISomethings2 {

            get { return this.ISomethings.Select(i => i.classB); }
        }

        public void RemoveSomething(ISomething2 s)
        {
            foreach (var somthing in this.ISomethings.Where(i => i.classB == s))
            {
                somthing.classB = null;
            }
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM