Ben:
Below is a copy of the two classes I mentioned if you build them in a C#
..dll and the reference it from a C++ /CLI application you will probably see
the same thing. For me if I inherit from DictionaryBase, it won't compile,
but if I inherit from StringDictionaryBase it will.
???
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, TValue> dictionary;
#region Constructors
public DictionaryBase()
{
dictionary = new Dictionary<TKey, TValue>();
}
public DictionaryBase(IDictionary<TKey,TValue> dictionary)
{
this.dictionary = new Dictionary<TKey,
TValue>(dictionary);
}
public DictionaryBase(IEqualityComparer<TKey> comparer)
{
dictionary = new Dictionary<TKey, TValue>(comparer);
}
public DictionaryBase(int capacity)
{
dictionary = new Dictionary<TKey, TValue>(capacity);
}
public DictionaryBase(IDictionary<TKey, TValue> dictionary,
IEqualityComparer<TKey> comparer)
{
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<TKey> Comparer
{
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,TValue> item)
{
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,TValue> item)
{
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,TValue> item in dictionary)
{
array[arrayIndex + count] =
new
KeyValuePair<TKey,TValue>(item.Key,item.Value);
++count;
}
}
#endregion
#region IDictionary<TKey,TValue> Members
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<TKey> IDictionary<TKey, TValue>.Keys
{
get { return this.Keys; }
}
bool IDictionary<TKey, TValue>.Remove(TKey key)
{
return this.Remove(key);
}
ICollection<TValue> IDictionary<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, TValue> item)
{
this.Add(item.Key,item.Value);
}
void ICollection<KeyValuePair<TKey, TValue>>.Clear()
{
this.Clear();
}
bool ICollection<KeyValuePair<TKey,
TValue>>.Contains(KeyValuePair<TKey, TValue> item)
{
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, TValue> item)
{
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
}
public class StringDictionaryBase : DictionaryBase<string, string>
{
public StringDictionaryBase()
{
}
}
Ben Voigt said:
Howard Swope said:
The DictionaryBase class has implementations for everything. All the
interface implementations call a series of virtual functions that can be
overriden by a derrived class, but are fully functional in there own
right.
Also what is the C++ definition for ExtraDataCollection? Does it list
interfaces? Is it generic?
Ben Voigt said:
"Howard Swope" <hswopeATtrafficDOTcom> wrote in message
I have implemented, in C#, a generic collection which has explicit
interface implementation
public abstract class DictionaryBase<TKey,TValue> :
IDictionary<TKey,TValue>,
ICollection<KeyValuePair<TKey,TValue>>,
IEnumerable<KeyValuePair<TKey,TValue>>,
IDictionary,
ICollection,
IEnumerable,
ISerializable,
IDeserializationCallback
{
...
}
If I try to inherit from this in C++ I get errors telling me that I am
missing implementations for some of my interface functions (errors
listed below). If within the same C# library I create a class that
inherits from my base class and then inherit from that in C++
everything works.
For example, I created the following class and then used this class
from which to inherit in C++. And everything works.
public class StringDictionaryBase : DictionaryBase<string,
string>
{
public StringDictionaryBase()
{
}
}
Any ideas why I can't inherit directly from my DictionaryBase class???
Which class actually implements the IEnumerable<T>, ICollection<T>, ...
interfaces?
Errors Received:
Error 2 error C3766: 'Hermes::Animation::ExtraDataCollection' must
provide an implementation for the interface method
'System::Collections::Generic::IEnumerator<T>
^System::Collections::Generic::IEnumerable<T>::GetEnumerator(void)'
c:\hermes\trunk\src\animation2\niwrapper\ExtraDataCollection.h 16
Error 3 error C3766: 'Hermes::Animation::ExtraDataCollection' must
provide an implementation for the interface method 'void
System::Collections::Generic::ICollection<T>::Add(System::Collections::Generic::KeyValuePair<TKey,TValue>)'
c:\hermes\trunk\src\animation2\niwrapper\ExtraDataCollection.h 16
Error 4 error C3766: 'Hermes::Animation::ExtraDataCollection' must
provide an implementation for the interface method
'System::Collections::Generic::ICollection<T>
^System::Collections::Generic::IDictionary<TKey,TValue>::Keys::get(void)'
c:\hermes\trunk\src\animation2\niwrapper\ExtraDataCollection.h 16
Error 5 error C3766: 'Hermes::Animation::ExtraDataCollection' must
provide an implementation for the interface method
'System::Collections::Generic::ICollection<T>
^System::Collections::Generic::IDictionary<TKey,TValue>::Values::get(void)'
c:\hermes\trunk\src\animation2\niwrapper\ExtraDataCollection.h 16
Warning 6 warning C4570: 'Hermes::Animation::ExtraDataCollection' : is
not explicitly declared as abstract but has abstract functions
c:\hermes\trunk\src\animation2\niwrapper\ExtraDataCollection.h 9
--
Howard Swope [hswope.swopeATnavteqDOTcom]
Senior Software Developer
Media Development
Navteq Traffic [
http://www.traffic.com]