tags:

views:

74

answers:

2

I have an application with lots of generics and IoC. I have an interface like this:

public interface IRepository<TType, TKeyType> : IRepo

Then I have a bunch of tests for my different implementations of IRepository. Many of the objects have dependencies on other objects so for the purpose of testing I want to just grab one that is valid. I can define a separate method for each of them:

public static EmailType GetEmailType()
{
  return ContainerManager.Container.Resolve<IEmailTypeRepository>().GetList().FirstOrDefault();
}

But I want to make this generic so it can by used to get any object from the repository it works with. I defined this:

public static R GetItem<T, R>() where T : IRepository<R, int>
{
  return ContainerManager.Container.Resolve<T>().GetList().FirstOrDefault();
}

This works fine for the implementations that use an integer for the key. But I also have repositories that use string. So, I do this now:

public static R GetItem<T, R, W>() where T : IRepository<R, W>

This works fine. But I'd like to restrict 'W' to either int or string. Is there a way to do that?

The shortest question is, can I constrain a generic parameter to one of multiple types?

+3  A: 

No; you cannot constrain a generic parameter to one of multiple types. Generic restraints are quite simple constructs, actually.

And I think you may shortly run into the fact that generic constraints don't participate in overload resolution. :(

Stephen Cleary
A: 

The shortest answer is: no.

A longer answer is that you can restrict, as you did, to a common base class or interface. But in the case of int and string, the common base class of int and string is Object, which obviously is not an interesting (nor legal if I remember correctly) constraint.

You can restrict a generic parameter to a class or struct, but again, it does not suit your needs.

I guess you are limited to checking at run-time if the type is legal.

Timores