[英]C#: “Cannot create an instance of the static class”
我正在将一些Java代码转换为C#,偶然发现以下奇怪的事情:
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(用法):
protected IActivation activation = new IActivation.S1();
看一下原始代码,很清楚这是什么意思:
new IActivation.S1();
来说,嵌套声明将进一步提高代码的可读性(例如, new IActivation.S1();
清楚地表明S1是IActivation的具体实现)。 有趣的是,C#并不喜欢定义整个事物的方式:“ 无法创建静态类'IActivation.S1的实例 ”。 有没有人知道如何重构该代码的方式,以便1.和2.将被保留?
在Java中, static
内部类没有对其封闭类型成员的隐式访问。 在C#中, 所有嵌套类型都没有对父类型成员的访问权限; 您无需在C#中添加修饰符来触发此行为。
在C#中, static
类是abstract sealed
,因此它们不能被创建或派生 - 这与Java中的含义不同。 此外,接口不能包含自己的类型声明。
尝试这样的事情:
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;
}
}
如果您的目标是以某种“可读”的方式提供默认实现(尽管我认为IActivator.S1()
本质上更具可读性......)那么您可以创建一个静态工厂类:
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();
}
}
}
但是,我对这个更具可读性或更有帮助的说法提出质疑。 当在特定类型的上下文中构造对象时,Visual Studio将显示该类型的所有子类型。 所以如果你这样做( |
代表游标):
IActivator foo = new |
您应该获得当前作用域中实现IActivotor的所有类的简洁列表。
不要将您的类标记为static
。
错误消息本身很清楚,S1类不能是静态的,因为您正在创建它的实例。 从S1中删除static关键字。 此外,访问修饰符和抽象修饰符在接口声明中无效。
在C#中,接口不能声明内部类型。
我的建议是使用Factory模式来获取正确的实例而不是接口中的嵌套类型(这会增加耦合/依赖关系)。
interface IActivation
{
double func(double inputput);
}
public static class ActivationFactory
{
IActivation GetImplA()
{
return new ImplA();
}
IActivation GetImplB()
{
return new ImplB();
}
}
class ImplA : IActivation { }
class ImplB : IActivation { }
如果IActivation
不必是接口,则可以将其转换为抽象类
public abstract class IActivation
{
public abstract double func(double inputput);
public class S1 : IActivation
{
public override double func(double input)
{
if (input > 0) return 1.0;
return 0.0;
}
}
}
这改变了代码的实际含义,但允许你说
var s1 = new IActivation.S1();
更新我能想到的主要问题是,如果你有一个扩展别的东西并实现这个接口的类它将无法工作(你不能从两个类继承)。 然后,您可以创建一个接口和一个实现抽象类的抽象类,但这有点傻。
另一种选择是
public interface IActivation {
// ...
}
public class Activation {
public class S1 : IActivation {
// ...
}
}
优点是您将IActivation保留为接口,但是您有另一个类乱丢您的命名空间。
在这两种情况下,您还没有从Java完成直接端口。
使用sigleton模式为每个S'i'实现和撕裂appart接口和实现如上所述由cdhowie
看来你不需要工厂 - 除非你的S'i'实例有自己的状态?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.