Similar Types Occurring in Both Libraries
Whose String is it anyway?
Over the last 15 years or so, the Eiffel class libraries have been a source for reusable software components for developers.
The Eiffel Base library contains classes for commonly used objects like different kinds of numbers, strings, files, and data structures.
But there are also libaries of Eiffel classes for sophisticated purposes like lexical analysis and parsing, data access, and graphical user interface development.
Likewise .NET is delivered with assemblies containing thousands of powerful types with similar purposes.
Working in Both Worlds
When we build software that has access to both the rich Eiffel libraries and the many useful .NET types, we inevitably run into types from both worlds that have similar names and purposes, but are still different types with different semantics.
The Case of Strings
The example of these similar types which will almost certainly get in your face is the string types. You may remember that we looked briefly at the case of the string types in Naming Conventions and Name Handling.
The Eiffel Base Library contains class STRING
; the .NET assembly contains type System.String
, which Eiffel for .NETusers see as SYSTEM_STRING
. At an abstract level both of these model sequences of characters. But they are not the same type. In fact, they are different in some important ways. For example, instances of System.String
are immutable. So you cannot append to an instance of System.String
. If you want to build a string by appending, you should use an instance of System.Text.StringBuilder
to do the appending, then extract the instance of System.String
from it. With STRING
it is permissible to append, so you don't need a helper like the System.Text.StringBuilder
type.
So the two types are similar at an abstract level, but different semantically. There are reasonable arguments for the design of each.
Many types in the delivered assemblies have properties which are strings or methods which return or take strings as arguments. In all these cases, the strings in question are instances of System.String
.
Many classes in the delivered Eiffel libraries have features involving strings, that is attributes which are strings or routines which return or take strings as arguments. In all these cases, the strings are instances of STRING
(except for those designed for .NET compliance).
In C# and VB.NET, if you specify a quoted string like "Hello World!"
in your code, that string will conform to type System.String
. If you do the same in Eiffel, then "Hello World!"
will be an instance of STRING
. In Eiffel terminology, "Hello World!"
appearing in source code is a manifest string.
What all this means to you is that you cannot use an instance of System.String
when an instance of STRING
is called for, and vice versa. Three out of four of the executable lines in the following code sample are invalid:
local
my_string: STRING
my_system_string: SYSTEM_STRING
do
my_system_string := "Hello World!" -- Invalid
my_string := "Hello World!" -- Valid
my_string := my_system_string -- Invalid
my_system_string := my_string -- Invalid
.
.
end
To handle this issue, the Eiffel for .NET class STRING
has two features which can be used when a string of the other type is needed.
The first of these features is a query to_cil
which returns an object of type System.String
which has a sequence of characters equivalent to that of the STRING
to which to_cil
is applied. The to_cil
can be applied to manifest strings by enclosing the manifest string in parentheses.
The other feature is a creation procedure named make_from_cil
which takes as an argument an instance of System.String
and initializes its target STRING
with a sequence of characters equivalent to that of the argument.
In the following sample, we use these features of STRING
to make all the lines from the previous sample valid.
local
my_string: STRING
my_system_string: SYSTEM_STRING
do
my_system_string := ("Hello World!").to_cil -- Valid
my_string := "Hello World!" -- Valid
my_string.make_from_cil (my_system_string) -- Valid
my_system_string := my_string.to_cil -- Valid
.
.
end
Other Similar Types
There are many other cases of types available from the .NET assemblies which have similar purpose and semantics to those found in the Eiffel libraries. Fortunately, there is none that you will have to deal with as often as strings.