CA1033: 인터페이스 메서드는 자식 형식에서 호출할 수 있어야 합니다.
TypeName |
InterfaceMethodsShouldBeCallableByChildTypes |
CheckId |
CA1033 |
범주 |
Microsoft.Design |
변경 수준 |
주요 변경 아님 |
원인
외부에서 볼 수 있는 unsealed 형식이 public 인터페이스의 명시적 메서드 구현을 제공하면서 외부에서 볼 수 있는 같은 이름의 대체 메서드를 제공하지 않습니다.
규칙 설명
public 인터페이스 메서드를 명시적으로 구현하는 기본 형식을 생각해 보십시오. 기본 형식에서 파생되는 형식은 인터페이스로 캐스팅되는 현재 인스턴스에 대한 참조(C#에서는 this)를 통해 상속된 인터페이스 메서드에만 액세스할 수 있습니다. 파생된 형식에서 상속된 인터페이스 메서드를 명시적으로 다시 구현하면 기본 구현에는 더 이상 액세스할 수 없습니다. 현재 인스턴스 참조를 통한 호출에서는 파생된 구현을 호출합니다. 이렇게 되면 재귀가 발생하고 결국 스택 오버플로로 이어집니다.
외부에서 볼 수 있는 Close() 또는 System.IDisposable.Dispose(Boolean) 메서드가 제공되면 이 규칙에서는 IDisposable.Dispose의 명시적 구현에 대한 위반 문제를 보고하지 않습니다.
위반 문제를 해결하는 방법
이 규칙 위반 문제를 해결하려면 같은 기능을 노출하고 파생 형식에서 볼 수 있는 새로운 메서드를 구현하거나 명시적이 아닌 구현으로 변경합니다. 주요 변경이 허용될 경우 형식을 sealed로 만드는 방법도 있습니다.
경고를 표시하지 않는 경우
명시적으로 구현된 메서드와 기능은 같지만 이름이 다른, 외부에서 볼 수 있는 메서드를 제공할 경우에는 이 규칙에서 경고를 표시하지 않아도 안전합니다.
예제
다음 예제에서는 이 규칙을 위반하는 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();
}
}
}