Declaration of an interface with Where

Asked

Viewed 121 times

8

I’m studying a lot Pattern design, because I think they solve a lot of things and it is very opportune to study them. I took this statement on the Macoratti website and I confess, I could not explain from the where. What does that mean?

public interface IRepository<T> where T : class

2 answers

9

This is declaring an interface as you already know. You should also understand that it is generic. That is, it can work with several types of objects, provided that when it is implemented a type is specified.

You probably know that T between the symbols of minor and major and coming soon after the where is a palceholder. It’s what we might call a super variable. It is not a variable in fact, but it is something to identify that there will be something else there when it is actually used. I will illustrate:

When you use IRepository<Cliente> is the guy Cliente which will be used in this interface.

What the where is that you can only use restricted types, you cannot use any type. In your example you can only use types that are classes. You can’t be a guy who’s a struct or enum, for example. But you may have classes, other interfaces or even delegations. It is a way to ensure that certain conditions of the type are met. For some reason this interface does not go well with other types.

You can restrict even more, you can use a specific type. You could use for example:

public interface IRepository<T> where T : IEnumerable

In this case you can only use types that are enumerable. It can be any type, but it must implement IEnumerable. Of course this is just an example for you to understand, I don’t know if it makes sense in this specific case. Following this example you can use:

new IRepository<List>();
new IRepository<Dicionary>();
new IRepository<String>();

I put in the Github for future reference.

So much List how much Dictionary or String implement IEnumerable, then can be used because they meet the restriction imposed in the above statement.

But I couldn’t use:

new IRepository<Buffer>();

Documentation (translated). See also about the keyword.

  • That is, the type of my interface should be a class, as far as I could understand and only one class.

  • It makes sense yes, it was just for learning, to understand the "thing".

  • Actually any type by reference. It can be class, interface or delegate. There’s this trick, even though it’s written class, not just her. To make the difference: http://answall.com/q/14490/101 and http://answall.com/q/16181/101

8

where T : class is a generic restriction and means that T should be a Reference type (one class, interface, or a delegate).

class StringRepository<string>{}
class EnumerableRepository<IEnumerable<string>>{}
class DelegateRepository<Func<string>>{}

The "opposite" restriction is where T : struct, which means that T should be a nullable value type - ie any struct except Nullable<T>.

class IntRepository<int>{}
class DoubleRepository<double>{}

You can find here a complete list of all possible generic restrictions in C#: Constraints on Type Parameters

  • I posted a comment and now I understand what you put. Where T : class, I was understanding that the type could only be a class and you put that can be a Class, Interface, Delegate. Is that right? Or did you mean that I may have Class, Interface, Delegate restrictions and so on? Less, of course, Nullable. That’s right?

  • 1

    @pnet, where T : class means that T can be any of these 3 types. The 3 examples I have put together will compile. In my opinion, the name of the restriction was poorly chosen, it should have been where T : reference, for example.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.