I'm struggling with XS0433 ("The type XX exists in both...") probably because I got something wrong with partial classes. The funny thing is that it did compile until 2 days ago...
Project 0:
CLASS dbAbstract inherit dbServer
...
END CLASS
Project 1 (including 0):
PARTIAL CLASS dbTABELLE inherit dbAbstract
(some generic ACCESSes which are not in dbAbstract)
END CLASS
Project 2 (including 0 and 1):
PARTIAL CLASS dbTABELLE inherit dbAbstract
(some overwritten methods which are also in dbAbstract)
END CLASS
In Project 3 I have:
function Start()
local TABELLE as dbTABELLE
(...)
Return
This suddenly tells me that the Type 'dbTABELLE' exists in both (1) and (2). What can cause this problem? Did I get the idea of partial classes wrong?
Note: if there are only some overwritten ACCESSes in the dbTABELLE block of (2) the error doesn't show up.
PARTIAL CLASS
PARTIAL CLASS
Stefan,
Partial classes have to be in the same assembly (project) to be merged by the compiler.
Robert
Partial classes have to be in the same assembly (project) to be merged by the compiler.
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
-
- Posts: 71
- Joined: Thu Jul 15, 2021 10:46 am
- Location: Germany
PARTIAL CLASS
Hi Robert,
then I have an architectural problem.
In VO we have that base class dbAbstract. The subclasses are generated code into a library on top of that. Then these subclasses are extended in several layers above by the developers. Because under VO strongly typed stuff needs to be in the same module as the class declaration it belongs to everything we extend in this way further above needs to stay late bound.
I was hoping to improve our X# code in terms of strongly typing everything. Since it is unavoidable to spread code over several libraries (aka projects): What would be the best practise here?
then I have an architectural problem.
In VO we have that base class dbAbstract. The subclasses are generated code into a library on top of that. Then these subclasses are extended in several layers above by the developers. Because under VO strongly typed stuff needs to be in the same module as the class declaration it belongs to everything we extend in this way further above needs to stay late bound.
I was hoping to improve our X# code in terms of strongly typing everything. Since it is unavoidable to spread code over several libraries (aka projects): What would be the best practise here?
PARTIAL CLASS
Stefan,
You could also add methods in a class hierarchy that was not yours (like inside GUI classes) between a grandparent and a grandchild, at the parent level.
It also allowed you to bypass calls in a hierarchy by calling methods in the class hierarchy, bypassing the super layer.
For security reasons, this is not allowed in .Net.
The only thing that I can think of right now is to implement some of these classes as ABSTRACT class, which forces the developers to implement the ABSTRACT methods in their code. You can still call the methods in the base library (because the signature is declared) but they have to be implemented in the subclasses that the developers write.
Robert
VO was very flexible, allowing you to build constructs like this, that violated all normal design rules.StefanUngemach post=25430 userid=7039 wrote: then I have an architectural problem.
In VO we have that base class dbAbstract. The subclasses are generated code into a library on top of that. Then these subclasses are extended in several layers above by the developers. Because under VO strongly typed stuff needs to be in the same module as the class declaration it belongs to everything we extend in this way further above needs to stay late bound.
I was hoping to improve our X# code in terms of strongly typing everything. Since it is unavoidable to spread code over several libraries (aka projects): What would be the best practise here?
You could also add methods in a class hierarchy that was not yours (like inside GUI classes) between a grandparent and a grandchild, at the parent level.
It also allowed you to bypass calls in a hierarchy by calling methods in the class hierarchy, bypassing the super layer.
For security reasons, this is not allowed in .Net.
The only thing that I can think of right now is to implement some of these classes as ABSTRACT class, which forces the developers to implement the ABSTRACT methods in their code. You can still call the methods in the base library (because the signature is declared) but they have to be implemented in the subclasses that the developers write.
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
-
- Posts: 71
- Joined: Thu Jul 15, 2021 10:46 am
- Location: Germany
PARTIAL CLASS
My proplem is that we have approx. 1.500 tables. Most of them use the standard methods, but some (or groups of some) overwrite these for some quiete complex mechanisms. I cannot force the developers to overwrite the same method for hundreds of classes (which I'd need if I made the base class ABSTRACT). Plus, there is code which can only be overwritten at a higher level (when additional libraries have been linked in), and that happens on several layers.
Are there perhaps other options (like doing something with Interfaces or delegates)?
Are there perhaps other options (like doing something with Interfaces or delegates)?
PARTIAL CLASS
Stefan,
Most likely, there are other ways to do this.
But I would need to see the design to give a meaningful advise
Robert
Most likely, there are other ways to do this.
But I would need to see the design to give a meaningful advise
Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
The Netherlands
robert@xsharp.eu
PARTIAL CLASS
...but the first that comes to mind, is to make the class in Project2 inherit form the one in Project1, like CLASS dbTABELLEchild inherit dbTABELLE. Then use dbTABELLEchild in Project2, while still using dbTABELLE in Project1.
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
-
- Posts: 71
- Joined: Thu Jul 15, 2021 10:46 am
- Location: Germany
PARTIAL CLASS
Wouldn't work since there is too much code relying on the generated classes (i.e. dbTABELLE). But due to the discussion which helped me understanding the PARTIAL concept better I started working with a modified approach. In a nutshell
- I generate all class declarations without any containing code into one file one level higher (like (2) in the example) - so all classes are known
- I replaced the ACCESSes fpr each class with an ENUM - these are mostly for code readability, and the ENUM seems to be handled in a different way by the compiler
- I allow one ore more additional PRGs for each subclass in (2), i.e. dbTABELLE.PRG, which extends the subclass with a PARTIAL statement
PARTIAL CLASS
Hi Stefan,
Just to be absolutely clear, the PARTIAL statement does not really do anything, it only tells the compiler that a class may span in several prg files in the same library, its memebrs will (or may) not be all defined within a certain CLASS...END CLASS construct. This was not needed in VO, because there was no concept of this CLASS...END CLASS container construct, this is the only reason why it is needed in X#. But it does not "extend" the class in any way.
Another thing that you could look into, is extension methods. Those are basically functions, but with special semantics, which make them appear like they are indeed extending a class in different libraries. This is not really the case, they can only access public members of the class (exactly like a function would be able to) and can only be methods, not ACCESS/ASSIGNs, but nevertheless they could be another option (in some cases), depending on the architecture of your system.
Just to be absolutely clear, the PARTIAL statement does not really do anything, it only tells the compiler that a class may span in several prg files in the same library, its memebrs will (or may) not be all defined within a certain CLASS...END CLASS construct. This was not needed in VO, because there was no concept of this CLASS...END CLASS container construct, this is the only reason why it is needed in X#. But it does not "extend" the class in any way.
Another thing that you could look into, is extension methods. Those are basically functions, but with special semantics, which make them appear like they are indeed extending a class in different libraries. This is not really the case, they can only access public members of the class (exactly like a function would be able to) and can only be methods, not ACCESS/ASSIGNs, but nevertheless they could be another option (in some cases), depending on the architecture of your system.
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu