Edward,
The .NET Framework 1.1 SDK documentation topic for class CollectionBase
includes a C++ sample, and this sample does compile and run correctly on
the .NET Framework 1.1.
This example does not compile with the C++ compiler that comes with the
..NET Framework 1.0 SDK, however. If I understand correctly, two
differences between VC++ 7.0 and VC++ 7.1 are at play here:
- If a __gc class declares a method whose name and parameter list match
an interface method, then VC++ 7.0 assumes that the programmer wants to
implement the interface method and, thus, requires that the return type
is covariant. VC++ 7.1, however, does not assume this. If the return
type is not covariant, VC++ 7.1 considers both methods to be unrelated.
- If a __gc class declares two methods with the same name and parameter
types, then VC++ 7.0 requires that they are both qualified with an
interface name. VC++ 7.1, however, allows one method to be unqualified.
In short, VC++ 7.0 behaves more like C++ and VC++ 7.1 behaves more like C#.
Your analysis contains some errors. See below.
[quoted text, click to view] Edward Diener wrote:
> In C++ an overridden virtual function in a derived class must have the exact
> same signature of the function which is overridden in the base class, except
> for the return type which may return a pointer or reference to a derived
> type of the base class's return type.
I agree.
[quoted text, click to view] > In .NET the overridden virtual function is similar, but an actual parameter
> of the function can be a derived reference from the base class's reference
> also.
I believe that, for all intents and purposes, this statement is false,
and that in .NET, a method m1 overrides a method m2 only if the
parameter types list and the return type of m1 are equal to those of m2.
In this case, .NET is more strict than C++, and not the other way
around. My belief is supported by all known current implementations, as
well as by the C# Language Specification, which says, in section 10.5.4:
"An override method overrides an inherited virtual method with the same
signature." The same section also says that it is an error if the
override declaration and the overridden base method do not have the same
return type. Interestingly, I was not able to find language in the
Common Language Infrastructure (CLI) specification that supports either
of our views. The CLI says that the callvirt instruction calls the
method that "matches" the name and signature specified in the
instruction. Note that in CLI terminology, the signature includes the
return type. The problem is that "to match" could be interpreted as "to
equal", but it could also be interpreted as allowing covariance.
This is very interesting food for language lawyers, but a more relevant
point is that creating a strongly typed collection class using
CollectionBase does not require covariance.
For example: Please see the Int16Collection example in the 1.1
documentation for CollectionBase. The set_Item(int,Int16) method does
not override the set_Item(int,object) method. These two methods are
unrelated. The Int16Collection class serves its purpose as a strongly
typed collection class, even in the absence of covariance.
[quoted text, click to view] > This dichotomy can create a problem when using MC++ to override virtual
> properties. In MC++ one can never override a virtual property by using a
> derived reference type for the base class's reference type. In .NET one can
> specify an overridden property which is a derived reference type from the
> base class's reference type.
Sentence 2 is true; sentence 3 is false.
[quoted text, click to view] > This dichotomy comes into play when creating a custom collection class in
> MC++. The typical custom collection in other .NET languages overrides the
> Item type in CollectionBase, not only to provide type-safe usage but to
> creating a more specific type than an 'object' reference which the
> collection editor in the Component Designer and Windows Form Designer will
> understand to allow specific types to be added to a collection.
Custom collection classes declare an Item property, and this property is
retrieved through reflection by the Designers, but this property does
not override the Item property declared by IList.
[quoted text, click to view] > In MC++, however, it appears that the Item type must still be the 'object'
> reference ( Object * in MC++ ) since it is impossible to override the
> set_Item function with a different type than an Object * because of
> paragraph 1 above. This means that because the get_Item and set_Item must
> refer to the same type, the type must be Object * for an MC++ custom
> collection class.
The point is that VC++ 7.0 does not allow a function declaration whose
name and parameter types list are equal to a function in a base type,
except if the declared function overrides the function in the base type.
VC++ 7.1 does allow this (for __gc classes at least).
[quoted text, click to view] > Is there a way around this difference between MC++ other .NET languages
> other than writing one's collections in another .NET language and creating a
> separate assembly just for the collection, or accepting the limitation of
> MC++ as far as the collection editor is concerned ?
I do not think it is possible in VC++ 7.0.
Greetings
Bart Jacobs