Reputation: 1504
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
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