Saravanan
Saravanan

Reputation: 7854

using a dictionary of string and interface in C#

I have an Interface called as IObSrc, I have few classes that implement this interface called as ObSrc1, ObScr2 etc..

Interface IObSrc
{
  string id;
}

I also have an interface called as IDtSrc, this interface inturn is implemented by a few classes called as DtSrc1, DtSrc2.

Interface IDtSrc
{
  IObSrc getObject();
  Dictionary<string,IObSrc> getObjects();
}

When i implement this interface from DtSrc1, and I return ObSrc1 from DtSrc1, there is no issue, but when i return Dictionary<string,ObSrc1> or Dictionary<string,ObSrc2>, i get an indication of typemismatch.

public class DtSrc : IDtSrc
{
  public Dictionary<string,IObSrc> getObjects()
  {
    Dictionary<string,ObSrc1> val1 = new ...'
    ...
    return val1;
  }

}

How can i solve this issue.

* EDITED *

I have one more query, what if a method should return a generic type that can be varied by the implementation.

Example:

interface IDtSrc<T> where T:IObSrc
{ 
  T ExecuteObject(string objId);
}

This will be used as

class DtSrc1 
{ 
  string ExecuteObject(string objId)
  {..}
}

and

class DtSrc2
{ 
 Dictionary<string,string> ExecuteObject(string objId)
 {..}
}

Kindly suggest a right procedure for this also.

Upvotes: 5

Views: 13433

Answers (2)

Adam Rackis
Adam Rackis

Reputation: 83358

If you declare a dictionary of type Dictionary<string,IObSrc>, then you cannot substitute a dictionary with type parameters that are different in any way, even if the new type parameters inherit from the original. That's why Dictionary<string, ObSrc1> and Dictionary<string, ObSrc2> are failing.

What you're trying to achieve is called type covariance, and it's not supported on Dictionary<TKey, TValue>. Type covariance is only supported on collections which are "read only"—namely IEnumerable<T>.

It may seem silly, but consider what could happen otherwise:

Dictionary<string, IObSrc> dict = new Dictionary<string, ObSrc1>(); //illegal
dict.Add("X", new Obsrc2());

If this were allowed, the second line would compile fine, but blow up at runtime.

Upvotes: 6

Yuriy Faktorovich
Yuriy Faktorovich

Reputation: 68667

You could use generics with a constraint

interface IDtSrc<T> where T:IObSrc
{
  IObSrc getObject();
  Dictionary<string,T> getObjects();
}

But your implementation of IDtSrc will only be able to return one type of IObSrc.

Upvotes: 6

Related Questions