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

Note: As shown in the above example, it is necessary to apply to_cil to a manifest string if you are assigning it to a System.String or passing it as an argument where a System.String is called for.
This is expected to change in a future release. It shall become unnecesary to apply to_cil to manifest strings. Instead, whether a STRING or System.String is needed will be determined by the context in which the manifest string is being used, and the proper type of object will be generated.

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.

cached: 04/19/2024 10:32:31.000 AM