Generic Interface class signature - c#

I get inheritance, I just don't get why this interface implements itself?
Also, please could you explain what the emboldened part does? Why can I not just say where T is IIdentifiableEntity, instead of all those comma separated sections?
public interface IDataRepository<T> : IDataRepository
**where T : class, IIdentifiableEntity, new()**

Theres more than one question here.. I'll tackle them one by one:
Why this interface implements itself?
It doesn't. There is two types here .. one generic .. one non-generic. Why does it implement the non-generic one? Who knows .. we need to see the entire data layer to understand that. Its important to realize they are two types though.
Why can I not just say where T is IIdentifiableEntity
Again, this depends on your use case. class enforces a reference type as the generic parameter. So, you will not be able to create an instance of IDataRepository<int>. This makes sense in a data layer.. as you generally want to persist entire objects/graphs and they are generally reference types. new() allows you to use var x = new T() in your generic type. Without it, you will get a compiler error if you try to instantiate an instance of your generic type parameter.

It is often useful to define interfaces either for generic collection classes, or for the generic classes that represent items in the collection. The preference for generic classes is to use generic interfaces, such as IComparable rather than IComparable, in order to avoid boxing and unboxing operations on value types. The .NET Framework class library defines several generic interfaces for use with the collection classes in the System.Collections.Generic namespace.
When an interface is specified as a constraint on a type parameter, only types that implement the interface can be used. The following code example shows a SortedList class that derives from the GenericList class. For more information, see Introduction to Generics (C# Programming Guide). SortedList adds the constraint where T : IComparable. This enables the BubbleSort method in SortedList to use the generic CompareTo method on list elements. In this example, list elements are a simple class, Person, that implements IComparable. Read

There are 2 different interface IDataRepository which is general and IDataRepository<T> which is generic and restricted to class which has parameter less constructor and implemented IIdentifiableEntity. This is useful when your application is not only tied to IDataRepository<T> but you might have another generic interface likeIDataRepository<T> where T: IEntity, and in some parts you want to treat them as one interface
For the next question if it only has where T : IIdentifiableEntity you can pass another interface or struct as T , but the architect wants developers to pass a class which has a parameter constructor as T

Related

Arrays vs Generic in C#

I have noticed that array, in c#, implements ICollection<T>. How can an array implement a generic container interface, yet not be generic itself? Is it possible for us to do the same?
Edit: I would also like to know how the array is not generic, yet it accepts any type and has type safety.
public class ListOfStrings : IList<string>
{
...
}
This is a great example that demonstrates that we can create non-generics from a generic (Thank you MarcinJuraszek!!). This collection would be stuck with strings. My guess is that it has nothing to do with the generic value type declaration of string and is some internal wiring that I am unfamiliar with.
Thank you again!
Yes, it's totally possible. You can declare something like this:
public class MyListOfStrings : IList<string>
{
}
and as long as you implement all the properties/methods IList<string> requires you to everything will work just fine. As you can see MyListOfStrings is not generic.
You should also remember that Arrays are special types, and there is a bunch of stuff going on with them that's not happening with regular user-defined types. Some of it is described on MSDN, and the part that seem to be related to your questions is here:
Starting with the .NET Framework 2.0, the Array class implements the System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>, and System.Collections.Generic.IEnumerable<T> generic interfaces. The implementations are provided to arrays at run time, and as a result, the generic interfaces do not appear in the declaration syntax for the Array class. In addition, there are no reference topics for interface members that are accessible only by casting an array to the generic interface type (explicit interface implementations). The key thing to be aware of when you cast an array to one of these interfaces is that members which add, insert, or remove elements throw NotSupportedException.
As you can see Array implements IList<T>, ICollection<T> and IEnumerable<T> in a special way, and it's not something you can do with your own type.

Is it possible to constrain the constructors of classes implementing an interface?

Is it possible to set a constrain that all classes implementing an interface must have, for example, an empty constructor? Like the where T : new() constraint in generic ?
No - its not possible to place any such constraints on derived classes or implementors of a given interface.
Such constrains generally wouldn't be a particularly good idea / useful anyway, as generally when working with an interface you are normally working with instances of objects that implement that interface in which case the object has naturally already been created and such constraints are redundant. (The exception of course being generics, in which case you can use the new() constraint).
My guess is that you are attempting to create some sort of plugin system and wish to constrain implementations of your plugin interface to have some default constructor that you can use for instantiation... if this is the case then there are normally better alternatives that you can use, such as the MEF.
Can you elaborate more on why exactly you need this?
There are only four ways I can think of that you might be given a class at run-time which isn't known at compile-time. You might be given an instance of an object which implements an interface, and want to produce another one like it. That scenario would best be handled by having the interface include a NewSimilarInstance() method. You might have a method in some class which gets passed a generic type parameter which is constrained to your interface. In that scenario, the routine which accepts the generic parameter could have a new() constraint. Otherwise, you could be given a .net System.Type object or some other representation (such a string) for the type. In these latter two scenarios, no compile-time validation is going to be meaningful; doing anything with the types will require Reflection, and so you may as well use Reflection to see if they allow the creation of new instances.
No, there's nothing like that. It would be slightly odd, given that the normal use of interfaces is that the code using an interface shouldn't need to care about how it was instantiated - they shouldn't care about what the implementation class is, just that it implements the interface.
If you have some special use for this, I suggest you just write unit tests for it - if all the implementations will be in the same assembly, it should be pretty straightforward to do so, and will catch any errors at nearly the same time as compile-time...
I think you need to use a virtual class for that.
As Justin said not only you can't constrain constructor signatures using an interface but also it's not possible using an abstract class.
Maybe if you would explain why you need to place such a constrain we could find some other solutions for your problem
Inject a Factory into your generic class that can instantiate your interface, and drop the new() constraint.
Something like:
public interface IFactory<out T>
{
T CreateInstance();
}
public class GenericClass<T>
{
private readonly IFactory<T> _factory;
public GenericClass(IFactory<T> factory)
{
_factory = factory;
}
public DoSomething()
{
//...
T foo = _factory.CreateInstance();
//...
}
}

Can I dictate that a C# type parameter must only be an interface type?

I would like to implement a generic C# class which looks roughly as follows:
abstract class Foobar<T> : AbstractBase, T
{ ... }
This fails because C# will only allow types after the base class to be interfaces, so next I try this:
abstract class Foobar<T> : AbstractBase, T where T : interface
{ ... }
But then I find that C# does not allow this form of type constraint. Only where T : struct and where T : class are allowed.
How can I dictate that a type parameter must only be an interface type?
Basically, you can't.
You can make a contstraint to a specific interface, but not a general one for all interfaces. So you can constrain to IEnumerable for example, but not any interface.
What do you need this for anyway?
The real problem with that code is that you are inheriting from a type parameter.
Trying to compile
abstract class Foobar<T> : T { ... }
will still fail with: error CS0689: Cannot derive from 'T' because it is a type parameter.
I think that this would be perfectly reasonable at least in the case of abstract classes, and I wanted this feature too, but the c# compiler just wont let you do that.
I believe that you misunderstand the meaning of where T : struct and where T : class.
A generic type constraint like this means that T must be a value type or a reference type respectively.
However, the purpose of an interface is to define a contract, which is a totally different concept as compared to value type vs. reference type semantics.
Therefore a restriction like where T : interface would make no sense.
If you want to know more, I would suggest you to read the C# Programming Guide on type constraints:
Constraints on Type Parameters (C# Programming Guide)
You can't in simple words.
This fails because C# will only allow types after the base class to be interfaces
This constraint is due to the lack of multiple inheritance in C#. Multiple inheritance can be approximated by the use of interfaces because the overriding methods are explicit. The same way a class can only extend one other class, but can implement multiple interfaces. The trick here is that the implementing class MUST define the body for a method, so that the implementation is specific on which method is called.
Using a where to limit T can be applied to one class, or several interfaces. You can not limit the range to several classes.

Using an abstract generic class in a dictionary as value without being specific about the type

Maybe a stupid question but when I have an abstract generic class, say A<T>, and I want to build a dictionary with the abstract class as value and some other type as key in a completely different class. How do I do that without specifying the type?
Dictionary<int, A<T>> dictionary doesn't compile of course.
2 possibilities, I would think:
Make the class that hosts the dictionary generic as well and let the type argument "trickle through"
Find a non-generic interface under which you can store the instances in the dictionary.
You can only do this if the type parameter has been defined for the class holding the dictionary. In other words, at compile time, the type of T is known.
So this will compile:
public class MyDictionaryWrapper<T>
{
private Dictionary<int, A<T>> myDict;
}
Can you define a non-generic abstract or interface that all A<T> will implement? This was our solution to a similar problem in our project; we had web control ancestors that were generic to any of our domain classes, so the domain class could be passed in as the DTO and bound/unbound by the control's codebehind. The descendants closed the generic specification, but that ancestor had to stay open, so to allow for collections of these controls independent of domain type, we extracted a non-generic base class from the generic base. Defining an interface would work similarly.
I worked around it by just storing a Type as the value and then work with that Type. Seemed like a cleaner solution.
I think I have to give up type safety in this case and remove the generic. I can't define a non-generic interface because the main method of this class receives an argument of the generic type and I can't make the containing class a generic one either.
However, since this method is currently the only one that has anything to do with the generic class I'm going to remove the generic and make the argument in the method of type object to workaround the problem. I'm going to have to check the type at the callers of this method.

Class vs Interface

Recently I was asked in an interview that, can an Interface be considered as a class in C#? I.e. is an interface is a class in C#?
I was confused.
What can be the answer?
No, an interface is not a class.
An interface is a set of method signatures and possibly properties that all relate to a single idea. For example, the IList interface will have methods for indexing, inserting, and getting the number of elements. However, it does not define any implementation details. The list interface could be implemented as a linked list, or a wrapped up array, or anything you want, as long as it defines those methods in the interface.
A class is the template from which to create an actual object. Classes are a collection of method signatures, plus the implementations of those methods.
So no, an interface is not a class, as it merely defines a specific contract, while a class defines the whole behaviour of the object.
Commenter SquareCog accurately points out that the above is not entirely true. Since classes can be subclassed, and methods overridden, the class' relationship to the actual behaviour of an object gets somewhat more complicated. I'm just going to handwave that problem away by saying that classes are individual entities. You can read the source code for a class and know what behaviour that class encompasses. However, at runtime, objects have types instead of classes. Types are the entire inheritance tree, instead of a singular class, and thus a type's behaviour could be defined over several different classes. Luckily, this does not change the basic conceptual difference that interfaces are contracts that can imply (through names, argument types, etc) certain implementations, but cannot enforce anything but the method signatures, while classes do define an implementation, even if that is not the actual implementation used at runtime.
From a logical perspective, they are very similar. As noted by others, an ABC1 with only public abstract members would serve almost the same purpose as an interface.
When you get down to the nuts and bolts of it, the two have a number of important differences.
A class can only inherit from one base classes, but can implement many interfaces.
A value type, already deriving from ValueType, cannot inherit from an ABC, but can implement an interface.
A class can contain fields and static members. An interface cannot.
A class can contain implementation, an interface cannot.
A class can have private and protected members, an interface cannot.
Abstract members of an ABC are always virtual. A class can implement an interface with non-virtual members.
1: Abstract Base Class
Yes, any abstract class that contains no implementation and consists of abstract methods only would be equivalent to interface.
A Java interface is not a class; it is a declaration of methods that need to be implemented by classes; a description of abilities, if you will. Abstract classes in Java are an interesting half-way point between proper classes and interfaces, as they define the available methods, but also provide some default implementations.
The fundamental difference between an abstract class and an interface in Java is that you can only extend one class; you can implement multiple interfaces. An abstract class describes what you are; an interface describes what you can do. What you are also defines what you can do -- but it has significantly stronger meaning.
In general, an Interface is a type that can be implemented by a class to indicate that the class exposes a behavior through a set of methods. For example, .Net has an ICollection interface that contains methods to interact with a collection.
In C++, an interface is a class where every method is abstract.
In Java and .Net, interfaces are independent types that are unrelated to classes.
Either way, classes can implement interfaces.
There could be several answers.
No, a class is not an interface - an interface defines a contract, a class is a type of object which can be created.
Yes, an interface can be viewed as a base class with only virtual methods - this is how interfaces are defined in C++.
It's helpful to regard .net as having three "safe" kinds of types in .net: interfaces, classes, and value-types (there are also things like pointers and such, but those are another story), and three main contexts classes may be used: storage locations, heap objects, and generic constraints.
Heap objects may be of any type, but all heap objects behave like class objects. Heap objects of interface type are rare; they are not generally created within .net but may be created by code designed to work with older object models. Heap objects of class types contain one storage location for each field; heap objects of value types contain one storage location whose type is the value type in question.
Storage locations may likewise be of any type, but value-type storage locations differ from the others. A storage location of class type or interface type holds a class reference. A value-type storage location contains either a value primitive (byte, integer, char, floating-point number, etc.) or else contains a storage location for each field of the value type (so, e.g., a storage location of type Point holds two storage locations of type Int32, each of which holds a signed-32-bit-integer primitive).
Generic constraints may also be of any type, but constraints of interface types do not confine the constrained generic type parameter itself as being a class type, interface type, or value type. A method declared void Foo<T>(T param) where T:IWowzo could be called with a parameter of class type, interface type, or value type. If the routine is called with a value-type parameter, then param and any other storage locations declared to be of type T will be stored as value types. If the routine is called with a parameter of class type or integer type, then param and any other storage locations declared to be of type T will be stored as class references. It's important to note that if T is itself an interface type (IWozo or a derivative) then param will be passed as a reference to a heap object, and will behave like one regardless of whether the type of the object instance is a class object or value type. If struct Bar implements IWowzo, and myBar is a variable of type Bar, calling Foo<Bar>(myBar) may yield different semantics from Foo<IWowzo>(myBar); in the former case, the parameter will behave as a value type and in the latter case it will behave as a class type.

Categories

Resources