4

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?

Anders Gustafsson
  • 15,837
  • 8
  • 56
  • 114
  • `interface IFoo where T: struct{ }` – Amit Kumar Ghosh Mar 24 '17 at 12:36
  • 4
    there is no support to resrict an interface to be implemented by only structs. – Selman Genç Mar 24 '17 at 12:37
  • 1
    Correct, and so is this `interface IBar : class { } `. You do not restrict an interface but you can extend it. That is what `interface IFoo : IComparable` is, it states that `IFoo` extends the `IComparable` interface (*not that it is restricted to `IComparable`*) – Igor Mar 24 '17 at 12:37
  • @AmitKumarGhosh That does not put the `struct` constraint on the implementing type. – Anders Gustafsson Mar 24 '17 at 12:38
  • @AmitKumarGhosh Nothing would hinder me from writing `class C : IFoo` – Bill Tür stands with Ukraine Mar 24 '17 at 12:38
  • It cannot be done like this, but maybe we can help with the workaround for an actual problem you are solving. – Evk Mar 24 '17 at 12:38
  • yes, but you can restrict the data type the class operates on. – Amit Kumar Ghosh Mar 24 '17 at 12:38
  • there is no such constaint in c# AFAK – BRAHIM Kamel Mar 24 '17 at 12:38
  • 3
    This sounds a bit like an XY problem, what are you trying to achieve? – DavidG Mar 24 '17 at 12:39
  • 3
    Implementing an interface in a struct normally is a **bad** idea... It nearly always causes boxing. No problem in doing it, it will work... But you shouldn't unless you know what you are doing... [Thread about it](http://stackoverflow.com/questions/63671/is-it-safe-for-structs-to-implement-interfaces) – xanatos Mar 24 '17 at 12:39
  • @xanatos but almost all built-in structs in .NET (like int and so on) implement a whole bunch of interfaces. – Evk Mar 24 '17 at 12:41
  • @DavidG Yes, it is an "XY" problem, but at this point I am content with getting a response to the above question. Thanks anyway. – Anders Gustafsson Mar 24 '17 at 12:41
  • 1
    @Evk i added a *But you shouldn't unless you know what you are doing*... I hope that Microsoft programmers are in the group of "know what you are doing" :-) – xanatos Mar 24 '17 at 12:42
  • 1
    You can implement generic interface with T restricted to struct and create a property `T Self {get;}`. If that is implemented by class - it will have to at least provide you some struct to work with. If implemented by struct - it can return itself. – Evk Mar 24 '17 at 12:46
  • @Evk Interesting thought with the `Self` concept. One upvote for the idea :-) – Anders Gustafsson Mar 24 '17 at 13:37
  • The one responsible for the downvote, please feel free to comment why you consider this to be a downvotable question. – Anders Gustafsson Mar 24 '17 at 14:04

3 Answers3

5

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. ...

Igor
  • 60,821
  • 10
  • 100
  • 175
3

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> { }
Community
  • 1
  • 1
Anders Gustafsson
  • 15,837
  • 8
  • 56
  • 114
  • Although a step in the right direction it would not stop you from writing `class BarClass : IBar { }` assuming that `BarStruct` is defined. – Igor Mar 24 '17 at 14:06
  • 1
    Yes, that's right. Maybe I got carried away there for a moment :-) Maybe there is no solution after all... – Anders Gustafsson Mar 24 '17 at 14:09
  • 1
    Although not water tight maybe its good enough for what you need. I upvoted it anyway for creativity :) – Igor Mar 24 '17 at 14:13
  • Thanks! Unfortunately it is not entirely what I need, but it was an entertaining exercise nevertheless. – Anders Gustafsson Mar 24 '17 at 14:15
  • @Evk :-) I have worked around the issue, so right now it is not worthwhile to describe it in more detail. But who knows, maybe I'll post a follow-up question... – Anders Gustafsson Mar 24 '17 at 14:27
2

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) { }
}
Ivan Kishchenko
  • 795
  • 4
  • 15
  • That is not the same as what the OP is asking though. Essentially they want `Bar` to be forced to be a `struct` instead of a `class` via a restriction on `IBar` – Igor Mar 24 '17 at 12:44
  • Yes, I am fully aware of this possibility, but it is not what I need. Thanks anyway. – Anders Gustafsson Mar 24 '17 at 12:44
  • Probably better: *interface IBar where T : struct, IBar* , because the sentence is ***the implementing type** is constrained* – xanatos Mar 24 '17 at 12:44