mattumotu
mattumotu

Reputation: 1504

interface generic return type

I have serveral classes with similar method signatures that I wish to capture in an interface:

namespace MyLib

public class ClientList
    public ICollection<Client> Fetch() {
    {
        //do stuff
       return this.CreateCollection();
    }

    private ICollection<Client> CreateCollection()
    {
        List<Client> clientList = new List<Client>();
        // populate list
        return clientList;
    }

public class ProductList
    public ICollection<Product> Fetch() {
        //do stuff
       return this.CreateCollection();
    }

    private ICollection<Product> CreateCollection()
    {
        List<Product> productList = new List<Product>();
        // populate list
        return productList ;
    }

I would like an interface with a method signature for Fetch that returns an ICollection, type undefined (as it will be different for every list). This will ensure each *list object will have a fetch method and new ones won't have 'getList' or other such named calls. After doing a bit of research I believe generics may be the way to go, but I'm unsure how.

I tried

public interface IDataRequest
    ICollection<T> Fetch<T>();

but when I implemented this as

public ICollection<Client> Fetch<Client>()

I got an error on 'return this.CreateCollection();':

Cannot implicitly convert type 'System.Collections.Generic.ICollection<MyLib.Client>' to 'System.Collections.Generic.ICollection<Client>'. An explicit conversion exists (are you missing a cast?)

I thought maybe it was because I wasn't specifying the namespace. but if I changed to

public ICollection<MyLib.Client> Fetch<MyLib.Client>()

then I got the error:

Type parameter declaration must be an identifier not a type

on Fetch<MyLib.Client>()

and finally if I changed it to:

public ICollection<MyLib.Client> Fetch<Client>()

then I got the error:

'MyLib.ClientList' does not implement interface member 'MyLib.IDataRequest.Fetch()'. 'MyLib.ClientList.Fetch()' cannot implement 'MyLib.IDataRequest.Fetch()' because it does not have the matching return type of 'System.Collections.Generic.ICollection'.

I don't have a big knowledge of generics and have reached the limit of what I can try with cargo cult attempts. Is what I want to do possible? If so can you show me both the interface method signature and an example of the class method definition.

As requested in a comment here is the client class:

namespace MyLib
{
    using System.Data;
    using System.Runtime.Serialization;

    [DataContract]
    public class Client
    {
        public Client(DataRow clientRecord)
        {
            this.clientId = clientRecord.Field<string>("ID");
            this.cphh = clientRecord.Field<string>("ID");
            this.name = clientRecord.Field<string>("Name");
            this.address = clientRecord.Field<string>("Address");

            if (CommonUtilities.GIS.ValidateOSMapRef(clientRecord.Field<string>("Locationd")))
            {
                this.location = string.Format(
                    "{0}, {1}",
                    CommonUtilities.GIS.ConvertMapRefToEasting(clientRecord.Field<string>("Locationd")),
                    CommonUtilities.GIS.ConvertMapRefToNorthing(clientRecord.Field<string>("Locationd")));
            }
        }

        [DataMember]
        public string clientId { get; private set; }

        [DataMember]
        public string name { get; private set; }

        [DataMember]
        public string address { get; private set; }

        [DataMember]
        public string location { get; private set; }

        [DataMember]
        public string cphh { get; private set; }
    }
}

Upvotes: 3

Views: 3593

Answers (1)

Enigmativity
Enigmativity

Reputation: 117064

You've defined your interface incorrectly. Try it like this:

public interface IDataRequest<T>
{
    ICollection<T> Fetch();
}

Then your classes look like this:

public class ClientList : IDataRequest<Client>
{
    public ICollection<Client> Fetch()
    {
        //do stuff
       return this.CreateCollection();
    }

    private ICollection<Client> CreateCollection()
    {
        List<Client> clientList = new List<Client>();
        // populate list
        return clientList;
    }
}

public class ProductList : IDataRequest<Product>
{
    public ICollection<Product> Fetch()
    {
        //do stuff
       return this.CreateCollection();
    }

    private ICollection<Product> CreateCollection()
    {
        List<Product> productList = new List<Product>();
        // populate list
        return productList ;
    }
}

That compiles nicely.

Upvotes: 4

Related Questions