Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 338
  • Last Modified:

Putting derived type in interface implementation

Suppose I have code like below. I'm getting errors that the List<string> cannot implement the interface member because of different matching type (error CS0738). Any way to overcome this? I sometimes need to implement it as List, sometimes as HashSet etc. and I wouldn't like to have two properties for the same thing, one returning ICollection and the HashSet.

Thanks in advance
public interface MyInterface<T> {
  ICollection<T> Entries {get;}
}

public class MyClass : MyInterface<string> {
  public List<string> Entries {get; private set;}
}

Open in new window

0
bovlk
Asked:
bovlk
2 Solutions
 
John ClaesSenior .Net Consultant & Technical AnalistCommented:
Bovlk

we're using the wrong interfaces

List inherits from IList and ICollection
http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx

an Collection inherits from IList and ICollection

The issue HashSet is not inheriting 1 of them
http://msdn.microsoft.com/en-us/library/bb495294.aspx#Y114

So this is not going to worjk using the ICOllection Interface as return Type.

Regards
poor beggar
0
 
bovlkAuthor Commented:
Both List<T> and HashSet<T> inherit ICollection<T>.
0
 
Carl TawnSystems and Integration DeveloperCommented:
You can't do it quite like that because the compiler isn't smart enough to implicitly upcast from ICollection<T> to List<T>. You have to expose the property as ICollection, but there is nothing to stop you using List<> as the underlying type:
    public class MyClass : MyInterface<string>
    {
        public ICollection<string> GetEntries { get { return wibble; } }

        private List<string> wibble;
    }

Open in new window

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Fernando SotoRetiredCommented:
Hi bovlk;

I tested your code and it seems to work for me. Can you post the actual code and at what line the compiler gives the error.

Fernando
0
 
bovlkAuthor Commented:
FernandoSoto: I created a new console app in VS 2008, .NET 3.5 and it does not compile with the following message: 'ConsoleApplication17.MyClass' does not implement interface member 'ConsoleApplication17.MyInterface<string>.Entries'. 'ConsoleApplication17.MyClass.Entries' cannot implement 'ConsoleApplication17.MyInterface<string>.Entries' because it does not have the matching return type of 'System.Collections.Generic.ICollection<string>'.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication17
{
    public interface MyInterface<T>
    {
        ICollection<T> Entries { get; }
    }

    public class MyClass : MyInterface<string>
    {
        public List<string> Entries { get; private set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}

Open in new window

0
 
Fernando SotoRetiredCommented:
Hi bovlk;

I am sorry. When I created a test program I had modified your slightly. The issue with the last post is that in your interface you have the type for Entries as ICollection and in your class you have it set to List. Change List to ICollection in your class. The code snippet below makes the MyClass more generic so that you can pass in the Type at run time. My code has a List<string> passed into MyClass and another instance using a HashSet<int> using the same class def.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {

        public interface MyInterface<T>
        {
            ICollection<T> Entries { get; }
        }

        public class MyClass<T> : MyInterface<T>
        {
            public MyClass(ICollection<T> myList)
            {
                Entries = myList;
            }

            public ICollection<T> Entries { get; private set; }
        }

        static void Main(string[] args)
        {
            List<string> testList = new List<string>() {"First Element", "Second Element", "Third Element"};
            MyClass<string> mc1 = new MyClass<String>(testList);
            List<string> testList2 = mc1.Entries as List<string>;

            foreach (string listMC in testList2)
            {
                Console.WriteLine(listMC);
            }

            HashSet<int> testHashSet1 = new HashSet<int>() { 10, 123, 56, 74, 999 };
            MyClass<int> mc2 = new MyClass<int>(testHashSet1);
            HashSet<int> testHashSet2 = mc2.Entries as HashSet<int>;

            Console.WriteLine("\n");

            foreach (int hashSetMC in testHashSet2)
            {
                Console.WriteLine(hashSetMC.ToString());
            }

            Console.ReadLine();

        }
    }
}

Open in new window


Fernando
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now