8

我正在做一个小项目,我遇到了这个问题。

项目输出是一个包含接口的库。如果可能的话,我想实现该接口并像这样密封其中的功能:

public interface ITest
{
    void SomeMethod();
}

class A : ITest
{
    public sealed override SomeMethod()
    {

    }
}

这个想法是让每个人都可以使用这个接口,并有一些专门的类来实现它。例外是我想确保如果有人创建了一个 A 类型的专门类,他/她将无法更改该方法的行为。

问题是您不能将“覆盖”关键字放在那里,因为该方法未在接口中声明为“虚拟”。而且您不能在界面中将其声明为“虚拟”,因为它是不允许的。而且您不能删除“覆盖”关键字,因为“密封”需要它。

欢迎任何解决方法或头脑风暴的想法,但如果有人能想出一个包含界面的解决方案,我会很高兴学习它!

谢谢!

编辑:忘记这个问题!就像 Ani 所说,我忘记了 C# 中的默认方法是密封的。似乎偶尔回到基础总是好的......

4

5 回答 5

23

我可能完全误解了这个问题,但是如果您打算将方法密封在 中A,您可以这样做:

class A : ITest
{
    public void SomeMethod()  { ... }
}

与 Java 不同,C# 中的方法默认是密封的。的子类A将无法覆盖该方法,因为它尚未被标记virtual

另一方面,如果您的意图是在接口中将方法标记为“几乎密封”,以便它强制实现类立即密封它,那是不可能的。规定这些实现细节不是(也不应该是)接口的业务 - 接口旨在表示规范

于 2011-03-22T03:40:15.827 回答
3

使用具有内部可见性的抽象基类。这个基类在库之外是不可见的,但允许您密封方法并且该类仍然实现接口。

public interface ITest
{
    void SomeMethod();
}

internal abstract class SuperA : ITest
{

    public abstract void SomeMethod();

}

class A : SuperA
{
    public sealed override void SomeMethod()
    {

    }
}
于 2011-03-22T03:44:59.490 回答
2

您对sealed关键字的理解不正确。作为方法修饰符,sealed用于防止virtual方法(在基类中定义)在下一代派生类中被覆盖。例如:

class Base
{
   public virtual void M() { }
}

class Derived : Base
{
   public sealed override void M() { }
}

class A : Derived
{
   public override void M() { } //compile error, M is sealed in Derived
}

开发人员总是可以使用new修饰符在派生类中定义一个同名的方法,从而隐藏基类中定义的方法。

如果有人创建了一个 A 类的特殊类,他/她将无法更改该方法的行为。

如果“特化类”是指从 A 派生的类,答案是:他总是可以隐藏 A 中的方法,但不能改变方法的行为。

于 2011-03-22T03:45:47.213 回答
1

为什么不使用像下面这样的抽象类。

还没有测试过,但这应该可以吗?

public abstract class Test
{
    public virtual void SomeMethod() {}
    //OR
    public abstract void SomeMethod();//MSDN says:
    //an abstract method is implicitly virtual
}

class A : Test
{
    public sealed override SomeMethod()
    {

    }
}
于 2011-03-22T03:41:59.080 回答
0

默认情况下,C# 中的方法是密封的。这是一个示例

class Program
{
    static void Main(string[] args)
    {

        A obj = new A();
        obj.SomeMethod();
        b ss = new b();
        ss.SomeMethod();
        Console.ReadLine();
    }
}

public interface ITest { void SomeMethod(); }

class A : ITest { public void SomeMethod() {

    Console.WriteLine("SomeMethod Called from Class A object");
} }

class b : A
{
    //public override void SomeMethod()
    //{
    //    Console.WriteLine("Called from Class B Object");
    //}
}
于 2011-03-22T03:59:54.400 回答