An interface in C# can inherit another interface, e.g.
interface IFoo : IComparable { }
On the other hand, the following declaration is illegal:
interface IBar : struct { } // Invalid syntax
Is there any way an interface can be declared so that the implementing type is constrained to be a struct?
Is there any way an interface can be declared so that the implementing type is constrained to be a struct?
No, that is currently not possible and neither is the inverse (ensuring an interface is implemented by a class).
As far as documentation goes the closest thing I was able to find was this Interfaces, Interfaces (c#), Inheritance - Interfaces. I doubt there will be anything on an official MS site simply because (in most cases) there is no documentation on non-existing features (ignoring feature requests or features in progress) and this could be considered a non-existent feature.
Closest excerpt I could find
A class or struct can implement multiple interfaces. ...
Actually, thanks to this splendid comment by user #Evk, I realized that it is almost possible to constrain the implementation of an interface to be a struct (or analogously, a class).
The interface could be implemented as a generic interface, where the generic type parameter is constrained to be a struct that implements the interface itself:
interface IBar<T> where T : struct, IBar<T> { }
Now I can declare a struct that implements IBar:
struct BarStruct : IBar<BarStruct> { } // Works fine.
But, I cannot declare a class that implements IBar in the same way, since the generic type parameter is restricted to be a struct:
class BarClass : IBar<BarClass> { } // Will not compile!
However, it is not a waterproof approach: as user #Igor points out in the comment below, the following will still compile:
class BarClass : IBar<BarStruct> { }
You can not declare interface of struct, because classes and structs can only implement the interfaces. But you can declare interface with generic parameter as struct:
interface IBar<T> where T : struct
{
void Foo(T val); // T always be struct
}
And implement this interface:
class Bar : IBar<int>
{
public void Foo(int val) { }
}
Related
This code is compiled in visual studio, what is it's usage
public class MyClass<T>
where T : MyClass<T>
Note where T : MyClass<T>
This is the recurring template pattern and is usually used so that a base class can refer to its real type statically. This is done in an attempt to preserve type-safety so that parameter or return values referred to in the base class track the current type in the hierarchy e.g
public class Animal<T> where T : Animal<T>
{
public abstract T GiveBirth();
}
public class Cat : Animal<Cat>
{
public override Cat GiveBirth() { return new Cat(); }
}
Without the type parameter the Animal base class method would only be able to define the return type of GiveBirth to be Animal, which may reduce type safety for the clients.
It may be acceptible if you control the entire hierarchy and can ensure that classes supply the correct type parameter, but note that it can be abused e.g.
public class Cat : Animal<Dog> { ... }
Another downside is that any clients need to take account of the generic type parameter if they want to be applied to the base class e.g.
public static void Feed<T>(Animal<T> animal) where T : Animal<T> { ... }
public static void Feed<T>(T animal) where T : Animal<T> { ... }
This is an example of the curiously recurring pattern. Eric Lippert has an excellent article on this, including why you should usually avoid it.
It might be extended like this:
public class MyChild : MyClass<MyChild>
The pattern doesn't really clue you as to why you want this generic. This is unlike most generics/constraints...e.g. if I have List<Giraffe> I can see the relationship; if I have MyGeneric<T, U> where T : IComparer<U>, I can see what T will do. With T : MyClass<T>, I really have no hints as to the relationships or usages here. Perhaps there's a...
abstract T Instance { get; }
...that you wish to have the stronger-typing of MyChild in the case of MyChild.
As an example of why this isn't so good, you could have MyOtherClass : MyClass<MyChild>, or you could have MyGrandchild : MyChild, neither of which are probably what you were trying to enforce.
For types which will only have a single layer of inheritance from an abstract base type, use of the described pattern will make it possible for the abstract base type to include methods which, when called on any member of a derived type, will return a member of that derived type. This can be a useful design feature, allowing for much cleaner caller code than would otherwise be possible. The biggest problem with this design is that because .NET has no support for covariant generic class parameters, the approach won't work with multiple layers of inheritance.
Given abstract class AnimalBase<T> where T:AnimalBase<T>, with method T Clone() and class Cat: AnimalBase<Cat>, code could say var newCat = someCat.Clone(); newCat.Meow(); rather than having to say var newCat = (Cat)(someCat.Clone()); newCat.Meow();. Unfortunately, there would be no way to have a type SiameseCat properly derives from Cat, since the only way to have mySiameseCat.Clone(); return a SiameseCat would be to have SiameseCat derive from AnimalBase<SiameseCat>, but that would prevent it from deriving from Cat.
If rather than having a class constrain to its own type, one instead defines a generic interface and constrains to that, one may avoid such difficulties. There would be no problem having SiameseCat derive from Cat while implementing IAnimal<SiameseCat>. Further, interfaces are covariant, so a type which implements IAnimal<SiameseCat> could implicitly also implement IAnimal<Cat> [if Cat was an abstract type that didn't implement the interface itself]. Every derivative of the class would have to provide its own implementations of any methods whose return value varies with the generic type parameter, but from the caller's perspective, the interface types could behave perfectly with derived classes.
It looks to be guaranteeing the type is two-dimensional (if that term makes sense here).
For example: Node<int> would end up being Node<Node<int>>.
When an abstract class implements an interface, it is required to also either define or declare the methods (as asked before):
public interface MyInterface
{
void Method();
}
public abstract class MyAbstractClass : MyInterface
{
public abstract void Method(); // required, even though MyAbstractClass does not implement
}
public class MyClass : MyAbstractClass
{
public override void Method()
{
}
}
public interface MyInterface2 : MyInterface
{
// no need to declare Method() -- why can't abstract classes do the same for unimplemented methods?
}
What is the design rationale of the c# language to require the definition of abstract methods of abstract classes that implement interfaces? It seems completely redundant for an abstract class to be required to define a method that it does not implement (and to make it even worse, for the class that actually implements the method to have to mark the method as override). I see no reason why an abstract class could not behave like MyInterface2, which inherits from MyInterface but does not need to declare MyInterface's methods.
An abstract class is a fully-fledged type, just except it cannot be instantiated. Hence its full contract must be declared even though some of its methods are not implemented. A user of a particular abstract class must be able to bind to all its methods, be they coming from interfaces or directly declared in the abstract class. It the methods from interfaces were not (at least) declared (if not even implemented) in the abstract class, the used couldn't bind to them.
Further, classes and interfaces are somewhat loosely-coupled. A class may declare a method, which is later mapped to a same-signature method in an interface which is implemented by its descendant. Hence it is again a “good idea” from the language-design viewpoint to require all methods of interfaces being directly implemented on an abstract class to be actually declared in it.
You can think of an interface as a detachable feature (except when explicit implementations are used). The abstract class may live on its own and its direct users need not to know of any of its interfaces.
It's a design feature that only virtual methods can be left without an implementation, because the technical mechanism of virtual methods needs to be leveraged for the whole concept of abstract classes work in practice.
UPDATE: Example:
public interface IFoo { void M(); }
public abstract class Bar : IFoo
{
public virtual abstract void M();
public void N() { }
}
public class Baz : Bar
{
public override void M() { … }
}
…
public void Method(Bar par)
{
par.M();
}
…
Baz x = new Baz();
Method(x);
The Method see the instance denoted by the variable x as Bar — neither as Baz nor as IFoo. In other words, the user of class Bar does not care of whether it implemented one, two, ten, or no interface at all. All it does is access its members. It rely's on Bar's contract, not of IFoos contract. Hence if Bar implements IFoo, it must define all members from IFoo.
A method you create in an abstract class that implements the interface doesn't need to be abstract. Abstract classes can contain non-abstract methods too and you can define a full implementation of the interface there. The inheriting classes wouldn't need to override any of those methods.
Also, this is described in MSDN for abstract classes:
An abstract class must provide implementation for all interface members.
An abstract class that implements an interface might map the interface methods onto abstract methods.
Notice the word "might", it's not "has to".
Please also note what MSDN says about implementing an interface:
When a class or struct implements an interface, the class or struct must provide an implementation for all of the members that the interface defines.
This is true for all kinds of classes and structures.
A class which implements IFoo with method void Bar() has the option of whether or not it wishes to expose a public method Bar(), or whether it wishes to use a non-public member to implement the interface [C# requires the direct implementation method to be either public or private; vb.net also allows protected scope, which is often the most useful sort for abstract classes].
There are two useful ways via which an abstract class could implement IFoo.Bar():
public abtract void Bar();
// or
protected abstract void IFoo_Bar(); // Note that the exact name is arbitrary
void IFoo.Bar() { IFoo_Bar(); }
Both implementations are reasonable. The first would make an unjustified presumption that a class would want to have a public method which appears nowhere in its code; the latter would require the compiler to 'guess' at what name should be given to the abstract method. Because there is no behavior which would be clearly better than any alternative, C# requires the programmer to specify which behavior is desired.
I have a Generic Base Class that I want to allow one of two types ITest or IBoldface.
My Base Class looks like this:
public abstract class BaseTestingCollections<T> where T : ITest, IBoldface
{
...
}
One of the classes that inherit it looks like this:
public class TestCollection : BaseTestingCollections<ITest>, ITestCollection
{
...
}
When I compile I get this error:
The type DomainLogic.ITest' cannot be used as type parameter 'T' in the generic type or method 'DomainLogic.BaseTestingCollections'. There is no implicit reference conversion from 'DomainLogic.ITest' to 'DomainLogic.IBoldface'.
Such an either/or restriction can't be done (as I'm sure you've noticed, the comma is more like && than ||). You can either make two different abstract classes with different names (one BaseTestingCollectionsTest<T> where T : ITest, the other BaseTestingCollectionsBoldface<T> where T : IBoldface), or remove the static restriction and put the check at runtime. Or make one of ITest or IBoldface extend the other, or extend a common interface, if they share members.
Here's an example of checking at runtime:
public abstract class BaseTestingCollections<T>
{
public BaseTestingCollections()
{
if (!typeof(ITest).IsAssignableFrom(typeof(T)) && !typeof(IBoldface).IsAssignableFrom(typeof(T)))
throw new Exception();
}
}
Well you're not satistfying the constraint you've specified. T has to extend/implement both ITest and IBoldFace.
Your constraint doesn't mean that it has to extend/implement one of the types - it has to do both. A type argument has to satisfy all the type constraints in order to be valid.
See MSDN on generic constraints for more information.
Per your own generic constraint, only those types which implement both ITest and IBoldface are suitable generic arguments for your BaseTestingCollection class.
It's not either-or, how could it be? What happens when you call method Bar from the ITest interface on a T which only implements IBoldFace, which in turn defines no method Bar? What is a compiler to do when faced with such a scenario?
There is no reasonable action to take. Your constraints apply all at the same time to the generic argument.
You can't express an "either-or" constraint like this with C# generics. Use a common base interface of some sort:
interface ITestOrBold {}
interface ITest : ITestOrBold {}
interface IBoldface : ITestOrBold {}
class BaseTestingCollections<T> where T : ITestOrBold {}
Obviously instead of ITestOrBold you should have some sensible abstraction.
I have a Generic Interface
public interface TheInterface<T> where T : IObject
I also have an object class that this interface works with
public class SomeObject : IObject
I then have a class that implements the interface
public class ClassThatWorksWithSomeObject : TheInterface<SomeObject>
This all works well enough. Later on I add a class that works with TheInterface class independent of what version of IObject he uses.
public class IDoStuffToInterface
{
public IDoStuffToInterface(TheInterface<IObject> interface)
{
//bla bla
}
}
Problem is I can't pass ClassThatWorksWithSomeObject in there, even if It inherits from the intreface and it's generic object inherits from IObject.
I guess there are some cases that it could be hurtful if it did, but I can't think of any.
Is there a way to do this better?
I don't know the detail impelmentation, you can try:
public interface TheInterface<out T> where T : IObject
if you are using C#4.0
I think what you're doing should work, but you may need to use the covariance and contravariance keywords.
You need to make you definition of TheInterface covariant so that it accepts the wider types of IObject:
public interface TheInterface<out T> where T : IObject
You should be able to do this in C#4.0 by marking the interface type as contravariant, but I think you can also get around this by making the IDoStuffInterface generic as well.
public class IDoStuffToInterface<T> where T : IObject
{
public IDoStuffToInterface(TheInterface<T> interface)
{
//bla bla
}
}
Since SomeObject qualifies for T and ClassThatWorksWithSomeObject implements TheInterface<SomeObject>, it should be acceptable as a parameter.
The other way I saw mentioned by tvanfosson was to make your IDoStuffToInterface class generic. That would work nicely as well, if (as it appears in the example) the TheInterface is being passed into the constructor and (presumably) stored in the class.
However, if it were just a function (or even a constructor) that uses the TheInterface and it isn't being stored in the class, it would probably be better to make the function itself generic and leave the class alone. For example:
public class IDoStuffToInterface
{
public void DoSomething<T>(TheInterface<T> theInterface) where T : IObject
{
//bla bla
}
}
This would allow you to do the following:
ClassThatWorksWithSomeObject myObject = new ClassThatWorksWithSomeObject();
IDoStuffToInterface actor = new IDoStuffToInterface();
actor.DoSomething(myObject);
That compiles without any problem because the compiler is able to tell by inference that you are actually calling
actor.DoSomething<SomeObject>(myObject);
Now, I think that using covariance is still probably the best option if you are in control of the interface definition. But I wanted to add this as another option for when you don't have that degree of control in your interface.
I want to achieve something like this in C# 3.5:
public void Register<T>() : where T : interface {}
I can do it with class or struct, but how to do it with an interface?
If you are asking about adding a constraint to a specific interface, that's straightforward:
public void Register<T>( T data ) where T : ISomeInterface
If you are asking whether a keyword exists like class or struct to constrain the range of possible types for T, that is not available.
While you can write:
public void Register<T>( T data ) where T : class // (or struct)
you cannot write:
public void Register<T>( T data ) where T : interface
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?
You can't demand that T is an interface, so you'd have to use reflection at runtime to assert this.
If possible, I went with a solution like this. It only works if you want several specific interfaces (e.g. those you have source access to) to be passed as a generic parameter, not any.
I let my interfaces, which came into question, inherit an empty interface IInterface.
I constrained the generic T parameter to be of IInterface
In source, it looks like this:
Any interface you want to be passed as the generic parameter:
public interface IWhatever : IInterface
{
// IWhatever specific declarations
}
IInterface:
public interface IInterface
{
// Nothing in here, keep moving
}
The class on which you want to put the type constraint:
public class WorldPieceGenerator<T> where T : IInterface
{
// Actual world piece generating code
}