Click here to Skip to main content
15,886,873 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,

I am trying to create a generic interface. Just a simple one to start:

C#
interface IFactory<T> where T: IModel
{
    T Get<T>(int id);
}

When I implement this interface I would like it to match this:
C#
public class MemberFactory : IFactory<Member>
{
    Member Get(int id)
    {

    }
}

but all i get is:
C#
public class MemberFactory : IFactory<Member>
{
    T Get<T>(int id)
    {

    }
}


I looked through the object library for examples (i.e. IList<member>) which does implement correctly, but I'm guessing that there is some meta information I'm missing?

Any help would be great. I tried to search t'internets but either my googlefu is not strong or the search terms lead to far too many basic tutorials. Anyway - I'll stop waffling.

Thanks ^_^
Posted

In your IFactory<t> interface the generic type parameter is specified at the interface level. However, your Get<t> method also specifies a generic parameter of type T... This is likely the problem. the type parameter T is valid for the whole interface and can be treated as a type. You don't need your Get() method to have a type parameter as well and can force a return type of "T" without it in your interface.

Once done, implementing the interface will be exactly as you desire.

C#
public interface IFactory<T> where T: IModel
{
    T Get(int id);
}

public class Member : IModel
{
}

public class MemberFactory : IFactory<Member>
{
    public Member Get(int id)
    {
        throw new NotImplementedException();  
    }
}
 
Share this answer
 
v4
Comments
PIEBALDconsult 28-Jan-15 11:41am    
I'm pretty sure MemberFactory will need to be generic.
Richard Deeming 28-Jan-15 11:43am    
Why? It's quite normal for a non-generic class to implement a generic interface - think IEquatable<T>, for example.
TechJosh 28-Jan-15 11:51am    
I don't see why that would be necessary. You're not trying to make a factory that can return instances of any type that matches the type parameter... your making a factory that returns a specific type. And your specific type is declared in the class declaration.

You could support multiple types in the same class if you wish, multiple specific types by implementing the IFactory<t> interface for each type. <pre lang="c#">public class MemberRoleFactory : IFactory<Member>, IFactory<Role> If you want to support all types (that match the IFactory<t> type constraints) you could make it generic but I don't think thats what is being asked here.
PIEBALDconsult 28-Jan-15 11:53am    
I wrote that before you posted V2.
TechJosh 28-Jan-15 11:56am    
Yeah, somehow my copy & paste munged <member> into an html tag.
Solution 1 explains the implementation of interface using implicit implementation where public modifier is essentially required (which you missed). However, this is only good if you really need to use this members in some other ways, not only through the interface (and it's best to avoid, in most cases).

In other cases, it's better to use the explicit implementation of the interface. It gives the access to the implemented member only throw the interface reference, which is clearer. Here is how:
C#
public class Member : IModel { /* ... */ }

public class MemberFactory : IFactory<Member>
{
    Member IFactory<Member>.Get(int id)
    {
        //...
    }
}


I also want to add that MemberFactory itself can better be generic. If some functionality depends on the specific generic types, you can implement all common functionality (common to generic parameters), make it abstract, and override the specifics in derived classes. This is how:
C#
public interface IModel { };
public interface IFactory<Member> where Member: IModel { Member Get(int id); }

public class Member : IModel { /* ... */ }

public class MemberFactory<Member> : IFactory<Member> where Member: IModel {
    Member IFactory<Member>.Get(int id) {
        return default(Member); //replace with real code
    }
    //overide is derived classes to create specialization:
    protected abstract void Something(Member member);
}



—SA
 
Share this answer
 
v4
Comments
Andy Lanng 28-Jan-15 12:40pm    
Ooh rly! could you post more on the generic Factories, please.

My end goal is to have a situation where Member m = Factory.Get(id) automatically knows which factory to use (in this case MemberFactory). I'm pretty sure I've done this before -_-
Thanks
Sergey Alexandrovich Kryukov 28-Jan-15 12:50pm    
I'm not going to write a whole big article on this topic, but I'll try to answer your question if you explain the ultimate goal or requirements more. Automatically knows — based on what? And so on... Most likely, I know what to do, but it could be far from your original question. (In particular, it could be related to more powerful technique: Data Contracts.)

And will you formally accept this answer?

—SA
Andy Lanng 28-Jan-15 14:14pm    
I will post as a new question so I can be more specific and you can post as solutions.
Thanks - answer accepted ^_^
Sergey Alexandrovich Kryukov 28-Jan-15 15:19pm    
You are welcome. As to the new question, if you want me to contribute, please don't forget to reply to this comment with the link to it.
Thank you.
—SA
Andy Lanng 29-Jan-15 4:22am    
Here you are : Generic-Factory-Class
Thanks

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900