How can I use interface as a C# generic type constraint?
The closest you can do (except for your base-interface approach) is "where T : class
", meaning reference-type. There is no syntax to mean "any interface".
This ("where T : class
") is used, for example, in WCF to limit clients to service contracts (interfaces).
How to put an interface constraint on a generic method in C# 3.5?
C# and the CLR don't support overall interface constraints, although you can constrain it to a particular interface (see other answers). The closest you can get is 'class' and check the type using reflection at runtime I'm afraid. Why would you want an interface constraint in the first place?
C# generic constraint for base class and interface
This is how you fix this object model:
interface IComponent { }
abstract class Component : IComponent { }
interface IA : IComponent { }
interface IB : IComponent { }
interface IAB : IA, IB { }
class ComponentA : Component, IA { }
class ComponentB : Component, IB { }
class ComponentAB : Component, IAB { }
abstract class Collection<T1> where T1 : IComponent
{
protected List<T1> Items;
}
class CollectionA : Collection<IA> { }
class CollectionB : Collection<IB> { }
class CollectionAB : Collection<IAB> { }
C#: How to force a generic type to be an interface?
A constraint that specified that T could be cast as M would also suffice in my specific circumstance.
It is possible to make a constraint where T must be derived from the type specified by another argument.
where T : M
c# extension method for a generic class with interface as type constraint
Yes, this can be done by making the method generic and adding a generic type constraint to the method, as follows:
public static void SomeMethod<T>(
this SomeClass<T> obj, ISomeInterface objParam)
where T : ISomeInterface // <-- generic type constraint
{
...
}
Implementing an interface with a generic constraint
For more corrective, implement interface explicitly:
public class Class1<T> : IInterface
where T : Test2
{
public T Test { get; private set; }
Test2 IInterface.Test
{
get { ... }
}
}
Then you can avoid compiled error.
Why to use generic with interface constraint?
The two interfaces are very different, because List<T>
and List<IBase>
are very different. Let's suppose there is a class A
that implements IBase
. This, for one, does not compile:
IGeneric noTypeParameter = ...
noTypeParameter.property = new List<A>();
But this does:
IGeneric<A> hasTypeParameter = ...
noTypeParameter.property = new List<A>();
This is because List
is not covariant on T
. In fact it is invariant. See also: Convert List<DerivedClass> to List<BaseClass>
If you use IEnumerable<T>
and IEnumerable<IBase>
, then both of the above code snippets will compile, but the two IGeneric
interfaces are still different, because:
IGeneric noTypeParameter = ...
IEnumerable<A> enumerable = noTypeParameter.property; // does not compile
IGeneric<A> hasTypeParameter = ...
IEnumerable<A> enumerable = noTypeParameter.property; //does compile
So basically, with the generic parameter, you are able to pass specific types of List
to the interface, and get specific types of List
out. However, you can't "store a property
of any IBase
implementation". Without a type parameter, you are able to store a property
of any IBase
implementation, but you can't get specific types out of/into IGeneric
.
C# generic method with interface type constraint
You should just create dedicated methods. The sample code with the if
shows that your current method doesn't do one thing. It does multiple.
Just go with:
GetEntity(42);
GetValue(13);
public IEntity GetEntity(long id)
{
return EntityDao.Get(id);
}
public IValue GetValue(long id)
{
return ValueDao.Get(id);
}
This is a lot cleaner on all layers:
GetEntity
vs.Get<IEntity>
- You clearly communicate what is possible. You don't have any runtime exceptions.
- Your get methods don't need any type switching.
If this will result in too many similar methods on your service, it is time to break out new classes, e.g. one for Entity
and one for Value
.
Then you could give your service properties that return the new classes. That's the same I am doing when implementing my query objects. It could then look like this: service.Values.Get(13)
and service.Entities.Get(42)
Related Topics
Htmlagilitypack -- Does <Form> Close Itself for Some Reason
Why Datetime.Addhours Doesn't Seem to Work
How Much Faster Is C++ Than C#
Write to Windows Application Event Log Without Event Source Registration
What's the Difference Between Anonymous Methods (C# 2.0) and Lambda Expressions (C# 3.0)
Mvcbuildviews Not Working Correctly
Async/Await Different Thread Id
Struct Constructor: "Fields Must Be Fully Assigned Before Control Is Returned to the Caller."
Can a Class Library Have an App.Config File
Put Wpf Control into a Windows Forms Form
Right Aligning Text in PDFpcell
Why Is Typedreference Behind the Scenes? It's So Fast and Safe... Almost Magical!
Is Enabling Double Escaping Dangerous
Add Two Integers Using Only Bitwise Operators
What Is the Correct Way to Read a Serial Port Using .Net Framework