By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,167 Members | 1,717 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,167 IT Pros & Developers. It's quick & easy.

This works from C#, but not C++ / CLI

P: n/a
This problem has been bugging me for a while. I have created a collection
class and implemented it in a C# library. If I inherit from this class in
another C# assembly and it works, but if I inherit from this class in a C++
/ CLI assembly it won't compile.

This indicates a problem in the CLR. Can anyone shed some light on this. The
class follows:

public abstract class DictionaryBase<TKey,TValue:
IDictionary<TKey,TValue>,
ICollection<KeyValuePair<TKey,TValue>>,
IEnumerable<KeyValuePair<TKey,TValue>>,
IDictionary,
ICollection,
IEnumerable,
ISerializable,
IDeserializationCallback
{
protected Dictionary<TKey, TValuedictionary;

#region Constructors
public DictionaryBase()
{
dictionary = new Dictionary<TKey, TValue>();
}

public DictionaryBase(IDictionary<TKey,TValuedictionary)
{
this.dictionary = new Dictionary<TKey,
TValue>(dictionary);
}

public DictionaryBase(IEqualityComparer<TKeycomparer)
{
dictionary = new Dictionary<TKey, TValue>(comparer);
}

public DictionaryBase(int capacity)
{
dictionary = new Dictionary<TKey, TValue>(capacity);
}

public DictionaryBase(IDictionary<TKey, TValuedictionary,
IEqualityComparer<TKeycomparer)
{
dictionary = new Dictionary<TKey, TValue>(dictionary,
comparer);
}

public DictionaryBase(int capacity, IEqualityComparer<TKey>
comparer)
{
dictionary = new Dictionary<TKey, TValue>(capacity,
comparer);
}

#endregion

#region Properties
public virtual IEqualityComparer<TKeyComparer
{
get { return dictionary.Comparer; }
}

public virtual int Count
{
get { return dictionary.Count; }
}

public virtual TValue this[TKey key]
{
get { return dictionary[key]; }
set { dictionary[key] = value; }
}

public virtual Dictionary<TKey,TValue>.KeyCollection Keys
{
get { return dictionary.Keys; }
}

public virtual Dictionary<TKey, TValue>.ValueCollection Values
{
get { return dictionary.Values;}
}

public virtual bool IsReadOnly
{
get { return false; }
}

public virtual bool IsFixedSize
{
get { return false; }
}

public virtual bool IsSynchronized
{
get { return false; }
}

public virtual object SyncRoot
{
get { return null; }
}
#endregion

#region Methods
public virtual void Add(TKey key, TValue value)
{
dictionary.Add(key, value);
}

public virtual void Clear()
{
dictionary.Clear();
}

public virtual bool ContainsKey(TKey key)
{
return dictionary.ContainsKey(key);
}

public virtual bool ContainsValue(TValue value)
{
return dictionary.ContainsValue(value);
}

public virtual bool Contains(KeyValuePair<TKey,TValueitem)
{
if (dictionary.ContainsKey(item.Key) &&
dictionary[item.Key].Equals(item.Value))
return true;
else
return false;
}

public override bool Equals(Object obj)
{
return dictionary.Equals(obj);
}

public virtual Dictionary<TKey,TValue>.Enumerator
GetEnumerator()
{
return dictionary.GetEnumerator();
}

public override int GetHashCode()
{
return dictionary.GetHashCode();
}

public virtual void GetObjectData(SerializationInfo info,
StreamingContext context)
{
dictionary.GetObjectData(info, context);
}

public virtual void OnDeserialization(Object sender)
{
dictionary.OnDeserialization(sender);
}

public virtual bool Remove(TKey key)
{
return dictionary.Remove(key);
}

public virtual bool Remove(KeyValuePair<TKey,TValueitem)
{
if (dictionary.ContainsKey(item.Key) &&
dictionary[item.Key].Equals(item.Value))
{
dictionary.Remove(item.Key);
return true;
}
else
{
return false;
}
}

public override String ToString()
{
return dictionary.ToString();
}

public virtual bool TryGetValue(TKey key, out TValue value)
{
if (dictionary.ContainsKey(key))
{
value = this[key];
return true;
}
else
{
value = default(TValue);
return false;
}
}

public virtual void CopyTo(KeyValuePair<TKey,TValue>[] array,
int arrayIndex)
{
int count = 0;
foreach (KeyValuePair<TKey,TValueitem in dictionary)
{
array[arrayIndex + count] =
new
KeyValuePair<TKey,TValue>(item.Key,item.Value);
++count;
}
}

#endregion

#region IDictionary<TKey,TValueMembers

void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
{
this.Add(key,value);
}

bool IDictionary<TKey, TValue>.ContainsKey(TKey key)
{
return this.ContainsKey(key);
}

ICollection<TKeyIDictionary<TKey, TValue>.Keys
{
get { return this.Keys; }
}

bool IDictionary<TKey, TValue>.Remove(TKey key)
{
return this.Remove(key);
}

ICollection<TValueIDictionary<TKey, TValue>.Values
{
get { return this.Values; }
}

TValue IDictionary<TKey, TValue>.this[TKey key]
{
get
{
return this[key];
}
set
{
this[key] = value;
}
}

#endregion

#region ICollection<KeyValuePair<TKey,TValue>Members

void ICollection<KeyValuePair<TKey,
TValue>>.Add(KeyValuePair<TKey, TValueitem)
{
this.Add(item.Key,item.Value);
}

void ICollection<KeyValuePair<TKey, TValue>>.Clear()
{
this.Clear();
}

bool ICollection<KeyValuePair<TKey,
TValue>>.Contains(KeyValuePair<TKey, TValueitem)
{
return this.Contains(item);
}

void ICollection<KeyValuePair<TKey,
TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
this.CopyTo(array,arrayIndex);
}

int ICollection<KeyValuePair<TKey, TValue>>.Count
{
get { return this.Count; }
}

bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
{
get { return this.IsReadOnly; }
}

bool ICollection<KeyValuePair<TKey,
TValue>>.Remove(KeyValuePair<TKey, TValueitem)
{
return this.Remove(item);
}

#endregion

#region IEnumerable<KeyValuePair<TKey,TValue>Members

IEnumerator<KeyValuePair<TKey, TValue>>
IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
{
return this.GetEnumerator();
}

#endregion

#region IEnumerable Members

IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}

#endregion

#region IDictionary Members

void IDictionary.Add(object key, object value)
{
this.Add((TKey)key,(TValue)value);
}

void IDictionary.Clear()
{
this.Clear();
}

bool IDictionary.Contains(object key)
{
return this.ContainsKey((TKey)key);
}

IDictionaryEnumerator IDictionary.GetEnumerator()
{
return this.GetEnumerator();
}

bool IDictionary.IsFixedSize
{
get { return this.IsFixedSize; }
}

bool IDictionary.IsReadOnly
{
get { return this.IsReadOnly; }
}

ICollection IDictionary.Keys
{
get { return this.Keys; }
}

void IDictionary.Remove(object key)
{
this.Remove((TKey)key);
}

ICollection IDictionary.Values
{
get { return this.Values; }
}

object IDictionary.this[object key]
{
get
{
return this[(TKey)key];
}
set
{
this[(TKey)key] = (TValue)value;
}
}

#endregion

#region ICollection Members

void ICollection.CopyTo(Array array, int index)
{
this.CopyTo((KeyValuePair<TKey,TValue>[])array,index);
}

int ICollection.Count
{
get { return this.Count; }
}

bool ICollection.IsSynchronized
{
get { return this.IsSynchronized; }
}

object ICollection.SyncRoot
{
get { return this.SyncRoot; }
}

#endregion

#region ISerializable Members

void ISerializable.GetObjectData(SerializationInfo info,
StreamingContext context)
{
this.GetObjectData(info,context);
}

#endregion

#region IDeserializationCallback Members

void IDeserializationCallback.OnDeserialization(object sender)
{
this.OnDeserialization(sender);
}

#endregion
}
--
Howard Swope [ mailto:howard.swopeATnavteqDOTcom ]
Technical Lead
Media Development
Navteq Traffic [ http://www.navteq.com ] [ http://www.traffic.com ]
Jul 29 '08 #1
Share this Question
Share on Google+
12 Replies


P: n/a
<"Howard Swope" <howard.swopeATnavteqDOTcom>wrote:
This problem has been bugging me for a while. I have created a collection
class and implemented it in a C# library. If I inherit from this class in
another C# assembly and it works, but if I inherit from this class in a C++
/ CLI assembly it won't compile.
Could you give more details than "it won't compile"? The error message
would be a good start - some sample (failing) code would be better. The
absolute ideal would be to cut down on the amount of code in your
collection class as well, until you've got a minimal failure.
This indicates a problem in the CLR.
Why? I'd have thought it would be a problem with the C++/CLI compiler
if anything.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jul 29 '08 #2

P: n/a
Howard Swope wrote:
This problem has been bugging me for a while. I have created a collection
class and implemented it in a C# library. If I inherit from this class in
another C# assembly and it works, but if I inherit from this class in a C++
/ CLI assembly it won't compile.

This indicates a problem in the CLR. Can anyone shed some light on this. The
class follows:
[... snip ...]
I did not have any trouble compiling this:

ref class MyDictionary : public DictionaryBase<int, System::String^>
{
};

If you could post your C++/CLI code here, and the error message you
get, we could probably tell you more (though it would be somewhat
offtopic in a C# group, I guess).

One thing though - are you sure you did not forget "ref" in your C++/
CLI class declaration?
Jul 30 '08 #3

P: n/a
The errors I am getting when I try to inherit from this class with

public ref class MyDictionary : DictionaryBase<String^, Object^>

{

public:

MyDictionary(void);

};

are
Error 1 error C3766: 'MyDictionary' must provide an implementation for the
interface method 'System::Collections::Generic::IEnumerator<T>
^System::Collections::Generic::IEnumerable<T>::Get Enumerator(void)'

Error 2 error C3766: 'MyDictionary' must provide an implementation for the
interface method 'void
System::Collections::Generic::ICollection<T>::Add( System::Collections::Generic::KeyValuePair<TKey,TV alue>)'

Error 3 error C3766: 'MyDictionary' must provide an implementation for the
interface method 'System::Collections::Generic::ICollection<T>
^System::Collections::Generic::IDictionary<TKey,TV alue>::Keys::get(void)'

Error 4 error C3766: 'MyDictionary' must provide an implementation for the
interface method 'System::Collections::Generic::ICollection<T>
^System::Collections::Generic::IDictionary<TKey,TV alue>::Values::get(void)'
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP********************@msnews.microsoft.com.. .
<"Howard Swope" <howard.swopeATnavteqDOTcom>wrote:
>This problem has been bugging me for a while. I have created a collection
class and implemented it in a C# library. If I inherit from this class in
another C# assembly and it works, but if I inherit from this class in a
C++
/ CLI assembly it won't compile.

Could you give more details than "it won't compile"? The error message
would be a good start - some sample (failing) code would be better. The
absolute ideal would be to cut down on the amount of code in your
collection class as well, until you've got a minimal failure.
>This indicates a problem in the CLR.

Why? I'd have thought it would be a problem with the C++/CLI compiler
if anything.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com

Jul 30 '08 #4

P: n/a
The errors I am getting when I try to inherit from this class with

public ref class MyDictionary : DictionaryBase<String^, Object^>

{

public:

MyDictionary(void);

};

are
Error 1 error C3766: 'MyDictionary' must provide an implementation for the
interface method 'System::Collections::Generic::IEnumerator<T>
^System::Collections::Generic::IEnumerable<T>::Get Enumerator(void)'

Error 2 error C3766: 'MyDictionary' must provide an implementation for the
interface method 'void
System::Collections::Generic::ICollection<T>::Add( System::Collections::Generic::KeyValuePair<TKey,TV alue>)'

Error 3 error C3766: 'MyDictionary' must provide an implementation for the
interface method 'System::Collections::Generic::ICollection<T>
^System::Collections::Generic::IDictionary<TKey,TV alue>::Keys::get(void)'

Error 4 error C3766: 'MyDictionary' must provide an implementation for the
interface method 'System::Collections::Generic::ICollection<T>
^System::Collections::Generic::IDictionary<TKey,TV alue>::Values::get(void)'

"Pavel Minaev" <in****@gmail.comwrote in message
news:92**********************************@a1g2000h sb.googlegroups.com...
Howard Swope wrote:
>This problem has been bugging me for a while. I have created a collection
class and implemented it in a C# library. If I inherit from this class in
another C# assembly and it works, but if I inherit from this class in a
C++
/ CLI assembly it won't compile.

This indicates a problem in the CLR. Can anyone shed some light on this.
The
class follows:
[... snip ...]

I did not have any trouble compiling this:

ref class MyDictionary : public DictionaryBase<int, System::String^>
{
};

If you could post your C++/CLI code here, and the error message you
get, we could probably tell you more (though it would be somewhat
offtopic in a C# group, I guess).

One thing though - are you sure you did not forget "ref" in your C++/
CLI class declaration?

Jul 30 '08 #5

P: n/a

"Howard Swope" <howard.swopeATnavteqDOTcomwrote in message
news:ON**************@TK2MSFTNGP04.phx.gbl...
The errors I am getting when I try to inherit from this class with

public ref class MyDictionary : DictionaryBase<String^, Object^>

{

public:

MyDictionary(void);

};

are
Error 1 error C3766: 'MyDictionary' must provide an implementation for the
interface method 'System::Collections::Generic::IEnumerator<T>
^System::Collections::Generic::IEnumerable<T>::Get Enumerator(void)'

Error 2 error C3766: 'MyDictionary' must provide an implementation for the
interface method 'void
System::Collections::Generic::ICollection<T>::Add( System::Collections::Generic::KeyValuePair<TKey,TV alue>)'

Error 3 error C3766: 'MyDictionary' must provide an implementation for the
interface method 'System::Collections::Generic::ICollection<T>
^System::Collections::Generic::IDictionary<TKey,TV alue>::Keys::get(void)'

Error 4 error C3766: 'MyDictionary' must provide an implementation for the
interface method 'System::Collections::Generic::ICollection<T>
^System::Collections::Generic::IDictionary<TKey,TV alue>::Values::get(void)'

The sample code in the documentation for the DictionaryBase class shows the
interfaces your derived class needs to implement.

See:
http://msdn.microsoft.com/en-us/libr...onarybase.aspx

Mark

--
Mark Salsbery
Microsoft MVP - Visual C++
Jul 30 '08 #6

P: n/a
Mark Salsbery [MVP] <MarkSalsbery[MVP]@newsgroup.nospamwrote:

<snip>
The sample code in the documentation for the DictionaryBase class shows the
interfaces your derived class needs to implement.

See:
http://msdn.microsoft.com/en-us/libr...onarybase.aspx
What I *think* Mark is saying (and it makes sense) is that you're
accidentally deriving from the framework's DictionaryBase class rather
than yours. Rename your class to Foo and try to derive from it then.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com
Jul 30 '08 #7

P: n/a
It would have been so nice if that was the case. I changed the name of the
class to Foo and came up with the same errors.

I think it is something with the signatures... The IL that C# is producing
is not like by C++. I know it relates directly to the generics. Because if I
inherit from this class in C# and then inherit from the newly created class
in C++. The C++ code will compile.

for example. I create another class:

public class StringDictionaryBase : DictionaryBase<string, string>

{

public StringDictionaryBase()

{

}

}

I can inherit from StringDictionaryBase in C++.

"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:MP*********************@msnews.microsoft.com. ..
Mark Salsbery [MVP] <MarkSalsbery[MVP]@newsgroup.nospamwrote:

<snip>
>The sample code in the documentation for the DictionaryBase class shows
the
interfaces your derived class needs to implement.

See:
http://msdn.microsoft.com/en-us/libr...onarybase.aspx

What I *think* Mark is saying (and it makes sense) is that you're
accidentally deriving from the framework's DictionaryBase class rather
than yours. Rename your class to Foo and try to derive from it then.

--
Jon Skeet - <sk***@pobox.com>
Web site: http://www.pobox.com/~skeet
Blog: http://www.msmvps.com/jon.skeet
C# in Depth: http://csharpindepth.com

Jul 31 '08 #8

P: n/a
On Jul 31, 5:17*pm, "Howard Swope" <howard.swopeATnavteqDOTcomwrote:
It would have been so nice if that was the case. I changed the name of the
class to Foo and came up with the same errors.

I think it is something with the signatures... The IL that C# is producing
is not like by C++. I know it relates directly to the generics. Because if I
inherit from this class in C# and then inherit from the newly created class
in C++. The C++ code will compile.
I can compile your code just fine here (if I put the required "using"
directives in the C# file, and "#using"/"using namespace" into the C++
file). So, no, it's probably nothing to do with signatures and IL, and
something with the compilation process. First of all, try to do the
same I did - take out the C# class to its own separate file (and
compile just that), and C++ class to its own file (and compile just
that too, only referencing the library produced from the C# file). If
that doesn't work, please provide the complete set of compilation
options you've used in both cases.
Aug 1 '08 #9

P: n/a
I submitted this as an incident to MS. It turns out that this is a bug in
the VS2005 compiler. I didn't mention the version of VC in my post which has
probably caused some confusion. The issue has been fixed on VS2008. I
appreciate everyone's advice.

"Pavel Minaev" <in****@gmail.comwrote in message
news:ca**********************************@b1g2000h sg.googlegroups.com...
On Jul 31, 5:17 pm, "Howard Swope" <howard.swopeATnavteqDOTcomwrote:
It would have been so nice if that was the case. I changed the name of the
class to Foo and came up with the same errors.

I think it is something with the signatures... The IL that C# is producing
is not like by C++. I know it relates directly to the generics. Because if
I
inherit from this class in C# and then inherit from the newly created
class
in C++. The C++ code will compile.
I can compile your code just fine here (if I put the required "using"
directives in the C# file, and "#using"/"using namespace" into the C++
file). So, no, it's probably nothing to do with signatures and IL, and
something with the compilation process. First of all, try to do the
same I did - take out the C# class to its own separate file (and
compile just that), and C++ class to its own file (and compile just
that too, only referencing the library produced from the C# file). If
that doesn't work, please provide the complete set of compilation
options you've used in both cases.
Aug 5 '08 #10

P: n/a
Howard Swope wrote:
I submitted this as an incident to MS. It turns out that this is a
bug in the VS2005 compiler. I didn't mention the version of VC in my
post which has probably caused some confusion. The issue has been
fixed on VS2008. I appreciate everyone's advice.
Was it the C++ or C# compiler that had the problem? For example, if you
compile the C# code in VS2005, can you use it in VC2008, or must the C# code
be recompiled with VS2008?
>
"Pavel Minaev" <in****@gmail.comwrote in message
news:ca**********************************@b1g2000h sg.googlegroups.com...
On Jul 31, 5:17 pm, "Howard Swope" <howard.swopeATnavteqDOTcomwrote:
>It would have been so nice if that was the case. I changed the name
of the class to Foo and came up with the same errors.

I think it is something with the signatures... The IL that C# is
producing is not like by C++. I know it relates directly to the
generics. Because if I
inherit from this class in C# and then inherit from the newly created
class
in C++. The C++ code will compile.

I can compile your code just fine here (if I put the required "using"
directives in the C# file, and "#using"/"using namespace" into the C++
file). So, no, it's probably nothing to do with signatures and IL, and
something with the compilation process. First of all, try to do the
same I did - take out the C# class to its own separate file (and
compile just that), and C++ class to its own file (and compile just
that too, only referencing the library produced from the C# file). If
that doesn't work, please provide the complete set of compilation
options you've used in both cases.

Aug 6 '08 #11

P: n/a
I am not sure. The gentleman at Microsoft said that the error was corrected
in VS2008. I am locked into 2005 here at work and hadn't even thought to try
it. I didn't push for further clarification. MS Said if I made a case that
my business was heavily impacted by the problem they would create a hotfix,
but I told them not to worry about it. I will probably just rewerite my
class in C++ / CLI. It's a pain but not that much work.

"Ben Voigt [C++ MVP]" <rb*@nospam.nospamwrote in message
news:el**************@TK2MSFTNGP05.phx.gbl...
Howard Swope wrote:
>I submitted this as an incident to MS. It turns out that this is a
bug in the VS2005 compiler. I didn't mention the version of VC in my
post which has probably caused some confusion. The issue has been
fixed on VS2008. I appreciate everyone's advice.

Was it the C++ or C# compiler that had the problem? For example, if you
compile the C# code in VS2005, can you use it in VC2008, or must the C#
code be recompiled with VS2008?
>>
"Pavel Minaev" <in****@gmail.comwrote in message
news:ca**********************************@b1g2000 hsg.googlegroups.com...
On Jul 31, 5:17 pm, "Howard Swope" <howard.swopeATnavteqDOTcomwrote:
>>It would have been so nice if that was the case. I changed the name
of the class to Foo and came up with the same errors.

I think it is something with the signatures... The IL that C# is
producing is not like by C++. I know it relates directly to the
generics. Because if I
inherit from this class in C# and then inherit from the newly created
class
in C++. The C++ code will compile.

I can compile your code just fine here (if I put the required "using"
directives in the C# file, and "#using"/"using namespace" into the C++
file). So, no, it's probably nothing to do with signatures and IL, and
something with the compilation process. First of all, try to do the
same I did - take out the C# class to its own separate file (and
compile just that), and C++ class to its own file (and compile just
that too, only referencing the library produced from the C# file). If
that doesn't work, please provide the complete set of compilation
options you've used in both cases.


Aug 7 '08 #12

P: n/a
As the thread mentions I submitted this as a bug to MS. I thought I would
post the final email that I received for those interested:

As we discussed, I'll go ahead and close this case. It was a pleasure
working with you. And as discussed we are marking this case non-dec (you
will not be charged for this incident as this is a bug in VC 8.0 compiler).

Don't hesitate to let us know if there's anything else we can help you with
in the future.

Here is a summary of the key points of the case for your records:

Problem:

You have a C# assembly where you have defined an abstract like
this :

public abstract class DictionaryBase<TKey,TValue:

IDictionary<TKey,TValue>,

ICollection< KeyValuePair<TKey,TValue,

IEnumerable< KeyValuePair<TKey,TValue,

IDictionary,

ICollection,

IEnumerable,

ISerializable,

IDeserializationCallback

Also all the methods are defined in this abstract class. When you inherit
from this class into a C++/CLI class following compiler errors are thrown:

Error 1 error C3766: 'MyDictionary' must provide an
implementation for the interface method
'System::Collections::Generic::IEnumerator<T>
^System::Collections::Generic::IEnumerable<T>::Get Enumerator(void)'

Error 2 error C3766: 'MyDictionary' must provide an
implementation for the interface method 'void
System::Collections::Generic::ICollection<T>::Add( System::Collections::Generic::KeyValuePair<TKey,TV alue>)'

Error 3 error C3766: 'MyDictionary' must provide an
implementation for the interface method
'System::Collections::Generic::ICollection<T>
^System::Collections::Generic::IDictionary<TKey,TV alue>::Keys::get(void)'

Error 4 error C3766: 'MyDictionary' must provide an
implementation for the interface method
'System::Collections::Generic::ICollection<T>
^System::Collections::Generic::IDictionary<TKey,TV alue>::Values::get(void)'

Environment :

Eligible Product : Visual Studio 2005 SP1

Cause:

This is a bug in VC8.0 compiler and its fixed in VC9.0 (Visual
Studio 2008) compiler. Currently there is no fix available for VC8.0
compiler.

You have informed us that you will be able to workaround the issue. If in
future you would like to get a fix for this please do let me know. And I
would help in submitting the request for fix to the devs. Also as I have
already informed that it would be the devs who would check out the
feasibility of producing a hotfix for this. It could also turnout that we
may / may not get the hotfix for this.

I am personally committed to providing excellent customer service and I
value any comments and suggestions that you may have. I would appreciate
your thoughts on not only the things I did right, but also on how I can
continue to improve my service in the future. I want to provide you with
this opportunity to make your voice heard. Please mail your feedback to my
manager whose contact details are given in my signature below.

I wish you all the best. Thank you for choosing Microsoft Developer
Support.

"Howard Swope" <howard.swopeATnavteqDOTcomwrote in message
news:uv****************@TK2MSFTNGP03.phx.gbl...
This problem has been bugging me for a while. I have created a collection
class and implemented it in a C# library. If I inherit from this class in
another C# assembly and it works, but if I inherit from this class in a
C++ / CLI assembly it won't compile.

This indicates a problem in the CLR. Can anyone shed some light on this.
The class follows:

public abstract class DictionaryBase<TKey,TValue:
IDictionary<TKey,TValue>,
ICollection<KeyValuePair<TKey,TValue>>,
IEnumerable<KeyValuePair<TKey,TValue>>,
IDictionary,
ICollection,
IEnumerable,
ISerializable,
IDeserializationCallback
{
protected Dictionary<TKey, TValuedictionary;

#region Constructors
public DictionaryBase()
{
dictionary = new Dictionary<TKey, TValue>();
}

public DictionaryBase(IDictionary<TKey,TValuedictionary)
{
this.dictionary = new Dictionary<TKey,
TValue>(dictionary);
}

public DictionaryBase(IEqualityComparer<TKeycomparer)
{
dictionary = new Dictionary<TKey, TValue>(comparer);
}

public DictionaryBase(int capacity)
{
dictionary = new Dictionary<TKey, TValue>(capacity);
}

public DictionaryBase(IDictionary<TKey, TValuedictionary,
IEqualityComparer<TKeycomparer)
{
dictionary = new Dictionary<TKey, TValue>(dictionary,
comparer);
}

public DictionaryBase(int capacity, IEqualityComparer<TKey>
comparer)
{
dictionary = new Dictionary<TKey, TValue>(capacity,
comparer);
}

#endregion

#region Properties
public virtual IEqualityComparer<TKeyComparer
{
get { return dictionary.Comparer; }
}

public virtual int Count
{
get { return dictionary.Count; }
}

public virtual TValue this[TKey key]
{
get { return dictionary[key]; }
set { dictionary[key] = value; }
}

public virtual Dictionary<TKey,TValue>.KeyCollection Keys
{
get { return dictionary.Keys; }
}

public virtual Dictionary<TKey, TValue>.ValueCollection Values
{
get { return dictionary.Values;}
}

public virtual bool IsReadOnly
{
get { return false; }
}

public virtual bool IsFixedSize
{
get { return false; }
}

public virtual bool IsSynchronized
{
get { return false; }
}

public virtual object SyncRoot
{
get { return null; }
}
#endregion

#region Methods
public virtual void Add(TKey key, TValue value)
{
dictionary.Add(key, value);
}

public virtual void Clear()
{
dictionary.Clear();
}

public virtual bool ContainsKey(TKey key)
{
return dictionary.ContainsKey(key);
}

public virtual bool ContainsValue(TValue value)
{
return dictionary.ContainsValue(value);
}

public virtual bool Contains(KeyValuePair<TKey,TValueitem)
{
if (dictionary.ContainsKey(item.Key) &&
dictionary[item.Key].Equals(item.Value))
return true;
else
return false;
}

public override bool Equals(Object obj)
{
return dictionary.Equals(obj);
}

public virtual Dictionary<TKey,TValue>.Enumerator
GetEnumerator()
{
return dictionary.GetEnumerator();
}

public override int GetHashCode()
{
return dictionary.GetHashCode();
}

public virtual void GetObjectData(SerializationInfo info,
StreamingContext context)
{
dictionary.GetObjectData(info, context);
}

public virtual void OnDeserialization(Object sender)
{
dictionary.OnDeserialization(sender);
}

public virtual bool Remove(TKey key)
{
return dictionary.Remove(key);
}

public virtual bool Remove(KeyValuePair<TKey,TValueitem)
{
if (dictionary.ContainsKey(item.Key) &&
dictionary[item.Key].Equals(item.Value))
{
dictionary.Remove(item.Key);
return true;
}
else
{
return false;
}
}

public override String ToString()
{
return dictionary.ToString();
}

public virtual bool TryGetValue(TKey key, out TValue value)
{
if (dictionary.ContainsKey(key))
{
value = this[key];
return true;
}
else
{
value = default(TValue);
return false;
}
}

public virtual void CopyTo(KeyValuePair<TKey,TValue>[] array,
int arrayIndex)
{
int count = 0;
foreach (KeyValuePair<TKey,TValueitem in dictionary)
{
array[arrayIndex + count] =
new
KeyValuePair<TKey,TValue>(item.Key,item.Value);
++count;
}
}

#endregion

#region IDictionary<TKey,TValueMembers

void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
{
this.Add(key,value);
}

bool IDictionary<TKey, TValue>.ContainsKey(TKey key)
{
return this.ContainsKey(key);
}

ICollection<TKeyIDictionary<TKey, TValue>.Keys
{
get { return this.Keys; }
}

bool IDictionary<TKey, TValue>.Remove(TKey key)
{
return this.Remove(key);
}

ICollection<TValueIDictionary<TKey, TValue>.Values
{
get { return this.Values; }
}

TValue IDictionary<TKey, TValue>.this[TKey key]
{
get
{
return this[key];
}
set
{
this[key] = value;
}
}

#endregion

#region ICollection<KeyValuePair<TKey,TValue>Members

void ICollection<KeyValuePair<TKey,
TValue>>.Add(KeyValuePair<TKey, TValueitem)
{
this.Add(item.Key,item.Value);
}

void ICollection<KeyValuePair<TKey, TValue>>.Clear()
{
this.Clear();
}

bool ICollection<KeyValuePair<TKey,
TValue>>.Contains(KeyValuePair<TKey, TValueitem)
{
return this.Contains(item);
}

void ICollection<KeyValuePair<TKey,
TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
this.CopyTo(array,arrayIndex);
}

int ICollection<KeyValuePair<TKey, TValue>>.Count
{
get { return this.Count; }
}

bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
{
get { return this.IsReadOnly; }
}

bool ICollection<KeyValuePair<TKey,
TValue>>.Remove(KeyValuePair<TKey, TValueitem)
{
return this.Remove(item);
}

#endregion

#region IEnumerable<KeyValuePair<TKey,TValue>Members

IEnumerator<KeyValuePair<TKey, TValue>>
IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
{
return this.GetEnumerator();
}

#endregion

#region IEnumerable Members

IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}

#endregion

#region IDictionary Members

void IDictionary.Add(object key, object value)
{
this.Add((TKey)key,(TValue)value);
}

void IDictionary.Clear()
{
this.Clear();
}

bool IDictionary.Contains(object key)
{
return this.ContainsKey((TKey)key);
}

IDictionaryEnumerator IDictionary.GetEnumerator()
{
return this.GetEnumerator();
}

bool IDictionary.IsFixedSize
{
get { return this.IsFixedSize; }
}

bool IDictionary.IsReadOnly
{
get { return this.IsReadOnly; }
}

ICollection IDictionary.Keys
{
get { return this.Keys; }
}

void IDictionary.Remove(object key)
{
this.Remove((TKey)key);
}

ICollection IDictionary.Values
{
get { return this.Values; }
}

object IDictionary.this[object key]
{
get
{
return this[(TKey)key];
}
set
{
this[(TKey)key] = (TValue)value;
}
}

#endregion

#region ICollection Members

void ICollection.CopyTo(Array array, int index)
{
this.CopyTo((KeyValuePair<TKey,TValue>[])array,index);
}

int ICollection.Count
{
get { return this.Count; }
}

bool ICollection.IsSynchronized
{
get { return this.IsSynchronized; }
}

object ICollection.SyncRoot
{
get { return this.SyncRoot; }
}

#endregion

#region ISerializable Members

void ISerializable.GetObjectData(SerializationInfo info,
StreamingContext context)
{
this.GetObjectData(info,context);
}

#endregion

#region IDeserializationCallback Members

void IDeserializationCallback.OnDeserialization(object sender)
{
this.OnDeserialization(sender);
}

#endregion
}
--
Howard Swope [ mailto:howard.swopeATnavteqDOTcom ]
Technical Lead
Media Development
Navteq Traffic [ http://www.navteq.com ] [ http://www.traffic.com ]

Aug 11 '08 #13

This discussion thread is closed

Replies have been disabled for this discussion.