Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Eiffel for .NET: An Introduction : Page 2

Eiffel Software Inc.'s Eiffel for .NET is now available as part of ESI's EiffelStudio. Eiffel for .NET combines the power of two object technology variants: Eiffel (including Design by Contract, multiple inheritance, genericity and seamlessness of software development) and .NET (including language interoperability, Web services and other advanced facilities).

Mapping non-CLS Compliant Mechanisms on .NET
Eiffel for .NET (in the EiffelStudio 5.1 IDE) is the only language in the .NET world to provide multiple inheritance and genericity.
Eiffel for .NET (in the EiffelStudio 5.1 IDE) is also the only language in the .NET world to provide multiple inheritance and genericity (see the "Eiffel Terminology" sidebar). Providing such advanced language mechanisms in an environment that does not support them (multiple inheritance and genericity do not conform to the Common Language Specification, CLS, of .NET) was quite a challenge. As a matter of fact, ESI wanted its implementation of Eiffel for .NET to be fully interoperable with the other .NET languages: any client should be able to reuse an Eiffel for .NET component in any way (client or inheritance relationship), and conversely Eiffel for .NET users should be able to reuse any .NET assembly (the unit of reuse in .NET). Multiple inheritance was a major implementation issue. The adopted solution takes advantage of the .NET support for multiple inheritance of interfaces (fully deferred classes): the Eiffel for .NET compiler shadows each class with an interface (see Figure 2). The "shadow interface" has the original class name (for example, A), since it is viewed from the outside world, and includes only interface elements (all the class features are declared as deferred). The implementation is moved to the automatically generated class called "Impl.ORIGINAL_CLASS_NAME" (for example, Impl.A). Here, "Impl" stands for "Implementation."

This mapping preserves the original inheritance hierarchy. As shown in Figure 2, interface C inherits from the interfaces A and B as the initial class C inherited from the classes A and B. Hence, there is no need for .NET programmers to know about the automatically generated classes (at least, client classes do not have to; descendants will have to inherit from the Impl class); they just remain a compiler issue. However, this technique raises a problem, which is class instantiation. As a matter of fact, the "non-Impl" entities are now interfaces, not classes, thus not instantiable. Hence, the Eiffel for .NET compiler generates a second set of classes, the "Create classes," which provide the necessary mechanisms to emulate class constructors (see Figure 3).

Figure 3: Complete mapping of multiple inheritance used in Eiffel for .NET.
You might be concerned of the cost of such a mapping, resulting in three times as many classes—three times as many objects at run time—as the original architecture. The ESI experience proved this mechanism to be reliable and efficient: the penalty introduced with the extra classes appears trifling comparing to the gain of having multiple inheritance. This mechanism fully relies on the .NET concept of namespace since Impl and Create are simply .NET namespaces. I will provide code examples later.

Genericity has been supported in Eiffel for .NET from the very beginning—since Eiffel#—contrary to multiple inheritance, which was only recently introduced with the second implementation of Eiffel on the .NET Framework. The technique retained for genericity is different from the one presented above for multiple inheritance. As a matter of fact, applying rules such as those just sketched would yield an explosion of classes—and an explosion of objects at run time—since the compiler would generate as many classes as class derivations; for example, you would have LIST [INTEGER], LIST [STRING], LIST [BOOLEAN], and so on, for just one generic class LIST [G]—where G is the formal generic parameter. This is clearly not scalable and is, therefore, unacceptable. Instead, the Eiffel for .NET compiler uses LIST [ANY], which in the .NET world corresponds to list of Object (Object is the top level class from which any .NET class inherits).

Covariance is also available in Eiffel for .NET, although the Common Language Runtime (CLR) does not support it (because of type safety issues that full covariance implies, also known as "polymorphic catcalls" in Eiffel). Eiffel for .NET implements a safe variant of covariance, with type checking, to avoid catcalls: the CLR raises an exception of type InvalidTypeException whenever a catcall may happen. Another advantage of this approach is that CLS compliant consumer tools can understand it, and benefit from the Eiffel for .NET covariance.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date