我有一个提供虚拟操作的c#-class。对于每个操作都存在同步和异步版本。
public class Foo{
public virtual void Bar(){..};
public virtual Task BarAsync(){..};
...
}
如果只有一个版本的操作被覆盖(操作的同步版本或异步版本),我希望编译器显示警告,例如编译器在覆盖Equals
而不覆盖{GetHashCode
时发出警告1}}或反之亦然。
更广泛地质疑:是否可以强制覆盖一个方法或属性强制覆盖其他属性或方法(通过编译器警告)。
答案 0 :(得分:3)
虽然这不是您实际问题的答案,但我要求您甚至不需要警告的方法。
为什么不创建一个带有可覆盖成员的抽象类,另一个用不带:
密封public class Foo{
public virtual void Bar(){..}
public virtual Task BarAsync(){..}
}
public abstract class ImplementIt : Foo {
public abstract override void Bar();
public abstract override Task BarAsync();
}
public sealed class DoNotImplementIt : Foo {
public override void Bar() {..}
public override Task BarAsync() {..}
}
现在,客户可以设计是否需要Foo
实现您的默认行为(= DoNotImplementIt
),或者他是否需要使用ImplementIt
的可自定义版本。在前一种情况下,他被迫在后一种情况下超越成员。
这种方法对于API用户来说更加清晰,因为他知道要从继承链中覆盖什么,而不是依赖凌乱的警告,而这些警告实际上甚至没有人照顾。
更好的方法是将Foo
定义为ImplementIt
和DoNotImplementIt
实现的接口(听起来很奇怪,但是你得到它)。从这个abstract override
中拯救你。通过这种方式,您还可以通过设置internal
来隐藏您的界面,并且只允许从API访问实现类。
答案 1 :(得分:1)
编写与执行具有相同效果的代码。
示例:
public interface IBarMethods
{
void Bar();
Task BarAsync();
}
public class Foo
{
public virtual IBarMethods DeMethods()
{
// return class containing default methods.
}
}
public class ImplementIt : Foo
{
public override IBarMethods DeMethods()
{
// return different methods.
}
}
答案 2 :(得分:0)
你可以写一个custom Code Analyzer。我自己从未使用过它。我们开始使用FxCop并为它编写了一些自定义规则。但这很难做到。使用Roslyn,这应该会容易得多。