0

The following question shows how to implement an interface that contains a class in java:

inner class within Interface

The code in Java is:

public interface A {
    class B {
    }
}

I was hoping the same thing was possible in C#, though I haven't yet been able to get anything working.

For reference, I have a class which makes lookups of key values, but the keys aren't named in a way that makes them easy to understand. I'd like to have a compile time lookup for keys, so the interface would be something like:

interface Lookup {
    class Keys {
        string SomeKey() => "0"
    }
}

Which means I suppose I have two questions:

  1. Is it possible to have an interface containing a class?
  2. Is there a better way of having a lookup between two strings (or any other values) that I can reference reliably at compile time?
OliverRadini
  • 6,238
  • 1
  • 21
  • 46
  • For your second question _"Is there a better way of having a lookup between two strings"_ I'd suggest to take a look at the [`Dictionary<,>` class](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?view=netframework-4.8) of the .NET Framework. Sounds like that might be what you're looking for. – bassfader Aug 15 '19 at 13:56
  • 1-it is not possible. 2-why do not you use a Dictionary? – Barış Akkurt Aug 15 '19 at 13:57
  • @bassfader A dictionary would indeed have most of the functionality I'm looking for, but I'd prefer to restrict the selection of keys to a known range at compile time – OliverRadini Aug 15 '19 at 13:57
  • 1
    @OliverRadini Then have you considered to simply use a custom `enum` type as key for your dictionary? – bassfader Aug 15 '19 at 13:58
  • @bassfader I'm not sure whether that'd ensure that all the keys of the `enum` exist and are available, though? – OliverRadini Aug 15 '19 at 14:00
  • 1
    why don't you just have a list of constants? (see my answer) – Tim Rutter Aug 15 '19 at 14:02
  • 5
    Judging by your answers, you might have an [XY Problem](https://en.wikipedia.org/wiki/XY_problem). – nkr Aug 15 '19 at 14:06
  • @nkr indeed, I did suspect this may be the case and added the second part of the question accordingly – OliverRadini Aug 15 '19 at 14:09

4 Answers4

4

You cannot have an class within an interface in C#. Interfaces are very simple in C#, and only provide a contract of functionality.

If you want to have a mapping between two strings, a Dictionary<string, string> may be of use to you.

Lukas
  • 498
  • 2
  • 12
  • 2
    I'm confused because the answers here aren't that old, but they all agree that it's not possible - but I'm looking right at it in my IDE right now. – Raphael Schmitz Nov 13 '21 at 10:10
  • @RaphaelSchmitz - I am also confused... This library makes heavy use of Classes within an Interface, I have ran the code locally, even added features to the code, it 100% works with nested classes WITHIN an interface: https://github.com/Singulink/Singulink.IO.FileSystem – jward01 Feb 26 '22 at 22:18
4

Simply put no you can't have a class inside an interface.

From your comments you are talking about having a restricted list of available strings for the keys so I'm wondering if you are in fact not looking for a string/string lookup but just want a convenient way of referencing a list of fixed strings. So a class with constants is all you need:

public static class Strings 
{
    public const string AString = "A";
    public const string BString = "B";
    public const string CString = "C";
}

Accessed like this:

var s = Strings.AString;
Tim Rutter
  • 4,549
  • 3
  • 23
  • 47
  • A list of constants is sounding like the closest thing to what I'm looking for at the moment, I suppose the data structure is more similar to an `enum`, except with strings as values; the advantage being that I can group all of these values. They could be defined separately, but then the interface has a new member for every key which is required, rather than a single data structure which holds all the keys – OliverRadini Aug 15 '19 at 14:04
  • 1
    Yes it is sort of like an enum with strings. I've amended my answer. – Tim Rutter Aug 15 '19 at 14:06
2

An interface can't itself have any instance data. It's implementation however can have any instance data it requires.

For example, a random example that might give you some insight:

public class SomeClass
{
    public string Key {get; set;}
}

public interface ISomeInterface
{
    string Value { get; set; }
    SomeClass SomeClass { get; set;}
}

public class SomeInterfaceImplementation : ISomeInterface
{
    public SomeInterfaceImplementation()
    {
        SomeClass = new SomeClass()
        {
            Key = "ABC"
        };
    }
    public string Value { get; set; }
    public SomeClass SomeClass { get; set; }
}

public class Program
{

    public static void Main()
    {
        var example = new SomeInterfaceImplementation()
        {
            Value = "A value",
        } as ISomeInterface;
        Console.WriteLine($"{example.SomeClass.Key} has value '{example.Value}'");
    }
}

In the example, the default constructor "generates" a key of ABC. We could implement this any way your logic requires. But you also have a contract that requires "SomeClass" and it's key is present.

Anywhere you want to use the contract, just accept the Interface and not an implementation class.

Additionally, feel free to play with the fiddle:

Austin T French
  • 5,022
  • 1
  • 22
  • 40
1

Most of the answers under this question are no longer true. Since C# 8.0, when default interface methods were added, it is possible for an interface to have member declaration that declare for example nested type. The following code is correct for C# 8.0:

public interface IA
{
    class B
    {
    }
}
Qwertyluk
  • 363
  • 3
  • 14