Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#: "Cannot create an instance of the static class"

Tags:

java

c#

.net

static

I'm in the process of converting some Java code to C# and stumbled across the following curious thing:

public interface IActivation {
    public abstract double func(double inputput);

    public static class S1 : IActivation {
        public double func(double input) {
            if (input > 0) return 1.0;
            return 0.0;
        }
    }
}

SomewhereElse (usage):

protected IActivation activation = new IActivation.S1();

Looking at the original code, it's clear what the intention of this was:

  1. Declare an interface and nested within it several static implementations of that interface (the code contains other implementations of IActivation, e.g. "S2", "S3" etc. which were omitted here).
  2. The typical usage scenario for this was to assign a variable to one specific implementation of that interface. Also, by the way you'd need to instantiate that variable, it's perfectly clear where those specific implementations belong to - in a manner of speaking, the nested declaration would further increase the readability of the code (e.g. new IActivation.S1(); makes it clear that S1 is a specific implementation of IActivation).

Interestingly, C# does not like the way the whole thing is defined: "Cannot create an instance of the static class 'IActivation.S1". Does anyone know a way of how to refactor that code so that 1. and 2. would be preserved?

like image 261
MrCC Avatar asked Nov 29 '22 16:11

MrCC


1 Answers

In Java, a static inner class has no implicit access to the members of its enclosing type. In C#, all nested types have no such access to their parent type's members; there is no modifier you need to add in C# to trigger this behavior.

In C#, static classes are abstract sealed, so they cannot be created nor derived -- this is not the same meaning as in Java. Additionally, interfaces cannot contain type declarations of their own.

Try something like this:

public interface IActivation {
    double Func(double inputput);
}

public class S1 : IActivation {
    public static readonly S1 Instance = new S1();

    private S1() { }

    public double Func(double input) {
        if (input > 0) return 1.0;
        return 0.0;
    }
}

If your goal is to provide default implementations in some "readable" way (though I dispute that IActivator.S1() is inherently more readable...) then you could create a static factory class:

public static class Activator
{
    public static S1 S1
    {
        get
        {
            return S1.Instance;

            // Or you could do this if you make the S1 constructor public:
            // return new S1();
        }
    }
}

However, I dispute the claim that this is more readable or helpful. Visual Studio will, when constructing an object in the context of a particular type, display all of that type's subtypes. So if you do this (| represents the cursor):

IActivator foo = new |

You should get a neat list of all of the classes in your current scope that implement IActivotor.

like image 51
cdhowie Avatar answered Dec 10 '22 02:12

cdhowie