Circular dependency between classes
-
Consider the following example..
public class Student { public string Name { get; set; } public IList Courses { get; set; } } public class Course { public string Name { get; set; } public IList Students { get; set; } }
In this example a circular dependency exists between Student class and Course class. The scenario arises when we are dealing with entity framework - wherein db tables are created as classes for a Student database management system. In case of C++ we use the concept of forward declaration for telling a class 'A' that another class called 'B' exists even before defining the class 'B'. Can anybody explain how C# compiler solves this problem of circular dependency between classes? PS: Please avoid telling me that the classes sould be redesigned to avoid circular dependency. The question is not related to designing since the below mentioned classes are very much from day-to-day programming scenarios.
If asking a question is bad; then not knowing the answer is worse!
-
Consider the following example..
public class Student { public string Name { get; set; } public IList Courses { get; set; } } public class Course { public string Name { get; set; } public IList Students { get; set; } }
In this example a circular dependency exists between Student class and Course class. The scenario arises when we are dealing with entity framework - wherein db tables are created as classes for a Student database management system. In case of C++ we use the concept of forward declaration for telling a class 'A' that another class called 'B' exists even before defining the class 'B'. Can anybody explain how C# compiler solves this problem of circular dependency between classes? PS: Please avoid telling me that the classes sould be redesigned to avoid circular dependency. The question is not related to designing since the below mentioned classes are very much from day-to-day programming scenarios.
If asking a question is bad; then not knowing the answer is worse!
With Interfaces. :-D
public interface IStudent { String Name ... } ; public class Student : IStudent { public string Name { get; set; } public IList Courses { get; set; } } public interface ICourse { String Name ... } ; public class Course : ICourse { public string Name { get; set; } public IList Students { get; set; } }
Or something like that.
-
Consider the following example..
public class Student { public string Name { get; set; } public IList Courses { get; set; } } public class Course { public string Name { get; set; } public IList Students { get; set; } }
In this example a circular dependency exists between Student class and Course class. The scenario arises when we are dealing with entity framework - wherein db tables are created as classes for a Student database management system. In case of C++ we use the concept of forward declaration for telling a class 'A' that another class called 'B' exists even before defining the class 'B'. Can anybody explain how C# compiler solves this problem of circular dependency between classes? PS: Please avoid telling me that the classes sould be redesigned to avoid circular dependency. The question is not related to designing since the below mentioned classes are very much from day-to-day programming scenarios.
If asking a question is bad; then not knowing the answer is worse!
I am by no means an expert, so don't take this answer as gospel. I am posting more to see if the gurus out there will correct any bad assumptions I have. As I believe: C++ is based on C. When C was created there was a need to keep compilers efficient - CPU time = $$$$. Therefore, the C language was designed with the idea that its compilers should not need to make multiple passes of the code. In a single-pass compiling strategy, you have to know what something is before you can use it. Hence procedures and variables had to be declared before they could be used. That led to the need for header files and forward declarations. I don't know if C++ compilers really need forward declarations, or whether it was just a carry over from C. But either way, this why I believe C++ has header files too. C# simply broke the tradition. If you allow your compiler to go over the code once and categorize the classes/methods/properties/fields and then go over it again to compile it, then there is no need for forward declaration, nor for header files. Am I way off base, Gurus?
Clive Pottinger Victoria, BC
-
I am by no means an expert, so don't take this answer as gospel. I am posting more to see if the gurus out there will correct any bad assumptions I have. As I believe: C++ is based on C. When C was created there was a need to keep compilers efficient - CPU time = $$$$. Therefore, the C language was designed with the idea that its compilers should not need to make multiple passes of the code. In a single-pass compiling strategy, you have to know what something is before you can use it. Hence procedures and variables had to be declared before they could be used. That led to the need for header files and forward declarations. I don't know if C++ compilers really need forward declarations, or whether it was just a carry over from C. But either way, this why I believe C++ has header files too. C# simply broke the tradition. If you allow your compiler to go over the code once and categorize the classes/methods/properties/fields and then go over it again to compile it, then there is no need for forward declaration, nor for header files. Am I way off base, Gurus?
Clive Pottinger Victoria, BC
-
That's right; Eric Lippert explained it in more detail on his blog[^]
Ah!! Multiple parsing is the secret!! :-D Thank you very much Clive for answering my question and thank you Harold for sharing that wonderful link. :thumbsup:
-
Ah!! Multiple parsing is the secret!! :-D Thank you very much Clive for answering my question and thank you Harold for sharing that wonderful link. :thumbsup:
In C++ the compiler only needed a function's prototype or a class declaration, both usually found in headers. The compiler left it to the linker to locate the implementations and resolve those dependencies. When working with C++, this is a common error. The compiler compiles all sources without problems, but the linker stops with an error because you forgot to tell it where to locate a library which belongs to one of the headers you have included. So you may very well see the linker as a second pass after compiling.
And from the clouds a mighty voice spoke:
"Smile and be happy, for it could come worse!"And I smiled and was happy
And it came worse.