CA1033: インターフェイス メソッドは、子型によって呼び出し可能でなければなりません
TypeName |
InterfaceMethodsShouldBeCallableByChildTypes |
CheckId |
CA1033 |
分類 |
Microsoft.Design |
互換性に影響する変更点 |
なし |
原因
シールされていない外部から参照できる型によって、パブリック インターフェイスを持つメソッドを明示的に実装しています。また、同じ名前を持つ外部から参照できる代替のメソッドがありません。
規則の説明
明示的にパブリック インターフェイス メソッドを実装する基本型があるとします。基本型から派生する型は、インターフェイスにキャストされた現在のインスタンス (C# では this) への参照によって、継承されたインターフェイス メソッドにのみアクセスできます。派生型が継承されたインターフェイス メソッドを (明示的に) 再実装する場合、基本の実装はアクセスできなくなります。現在のインスタンス参照を使用した呼び出しによって、派生した実装が呼び出されます。その結果、再帰が発生し、最終的にスタック オーバーフローになります。
この規則は、外部から参照できる Close() または System.IDisposable.Dispose(Boolean) の各メソッドが提示されているときに IDisposable.Dispose が明示的に実装されていても、違反をレポートしません。
違反の修正方法
この規則違反を修正するには、同じ機能を公開する新しいメソッドを実装して派生型から参照できるようにするか、明示的ではない実装に変更します。互換性に影響してもよい場合、型をシールする方法もあります。
警告を抑制する状況
明示的に実装したメソッドと機能は同じで名前は異なる、外部から参照できるメソッドを用意した場合は、この規則による警告を抑制しても安全です。
使用例
この規則に違反している型 ViolatingBase と、規則に適合する型 FixedBase を次の例に示します。
using System;
namespace DesignLibrary
{
public interface ITest
{
void SomeMethod();
}
public class ViolatingBase: ITest
{
void ITest.SomeMethod()
{
// ...
}
}
public class FixedBase: ITest
{
void ITest.SomeMethod()
{
SomeMethod();
}
protected void SomeMethod()
{
// ...
}
}
sealed public class Derived: FixedBase, ITest
{
public void SomeMethod()
{
// The following would cause recursion and a stack overflow.
// ((ITest)this).SomeMethod();
// The following is unavailable if derived from ViolatingBase.
base.SomeMethod();
}
}
}