简体   繁体   中英

Can a Custom C# object contain a property of the same type as itself?

If I have created the following Employee<\/strong> object (simplified)...

 public class Employee
    {
        public Employee()
        {       
        }

        public String StaffID { get; set; }
        public String Forename { get; set; }
        public String Surname { get; set; }
    }

An object can<\/strong> indeed have a reference to an object of its own type.

Constructors can have multiple overloads:

public Employee(Employee manager)
{
   this.Manager = manager;
}

Yes, an object can contain references to other objects of the same class.

public class Employee
{
    public Employee(Employee manager)
    {
        this.Manager = manager;
    }

    public String StaffID { get; set; }
    public String Forename { get; set; }
    public String Surname { get; set; }

    public Employee Manager { get; set; }
}

The only scenario where this isn't<\/em> possible is with a struct<\/code> ; a struct<\/code> is contained directly<\/strong> (rather than being a fixed-size reference to the data), so the size of an Employee<\/code> struct would have to be "the size of the other fields plus the size of an Employee", which is circular.

struct Foo {
    Foo foo;
}

First, the answer is Yes<\/strong> an object can have a field that contains an instance of itself. It can even have methods that accept or return the instances of the same class, and it can even depend on itself in the definition of the class, eg:

public class Person : IComparable<Person> //legal, recursive definition
{
   //fields (or properties) that are of type Person
   public Person Father;
   public Person Mother;
   public List<Person> Children;

   // method that takes a Person as a parameter
   public bool IsParent(Person potentialParent)
   {
      ....
   }

   //method that returs a Person
   public Person Clone()
   {
      //TODO: real implementation coming soon
   }

   public Person(){}

   //constructor that takes persons as arguments
   public Person(Person father, Person Mother)
   {
      Father = father;
      Mother = mother;
   }
}

是的,您可以在Employee中拥有Employee并且它不会导致无限循环,默认情况下Employee对象的Manager属性将为null

I tried this way and it worked for me:

class Program
{
    static void Main(string[] args)
    {
        A a = new A(new A());
    }
}

public class A
{
    public string Name { get; set; }
    public A a;

    public A() { }
    public A(A _a)
    {
        a = _a;
    }
}

It works, you can just try s.th. like:

public class A
{
    public A test { get; set; }
}

Specifically on the issue of construction (I've +1'd Odeds answer) - as you say constructing an instance in the constructor is a bad move.

But then ask yourself - why would you ever need to anyway. In your Manager / Employee case - you can't always be sure that an employee always has a manager, and if they don't then you shouldn't be using a new ed empty instance to signify that, but a null.

When your type will have public get/set accessors on the properties, generally you're likely to be loading these object trees from some external source, in which case you have nothing to worry about. Equally, you can have a constructor that accepts other Employee instances for Manager/Employee relationships etc.

You should also be checking for circular relationships in that constructor as well - ie an employee can't be someone's manager and their employee - try walking the child->parent relationship for that and see if it ever ends!

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