명시적인 getter 전용 인터페이스 구현에 private setter를 사용하는 것은 왜 불법입니까?
나는 구현에 반대하는 것이 아니라 인터페이스에 대한 프로그래밍이 일반적으로 바람직하다고 생각하기 때문에 암시 적 인터페이스 구현보다 명시적인 인터페이스 구현을 선호하는 경향이 있으며 웹 서비스를 다룰 때 종종 필요합니다.
즉, 명시 적 인터페이스 선언에서는 다음이 불법이고 암시 적 선언에서는 합법적 인 이유가 궁금합니다.
interface IConnection
{
string ConnectionString { get; }
}
class Connection1 : IConnection
{
// private set is illegal, won't compile
string IConnection.ConnectionString { get; private set; }
}
class Connection2 : IConnection
{
// private set is legal now, it is not part of the interface
string ConnectionString { get; private set; }
}
명시 적 인터페이스와 암시 적 인터페이스를 모두 갖는 것이 합법적이므로이 문제를 해결하는 방법을 알고 있으며 암시 적 인터페이스 구현을 완전히 비공개로 만들 수 있습니다.
그러나 나는 이것의 이유에 대해 궁금합니다. 기술적으로 내부적으로 컴파일 된 private 메서드 set_IConnection_ConnectionString
는 인터페이스의 일부일 필요가 없기 때문입니다. 암시 적 구현 상황에서와 같이 인터페이스의 일부가 아닌 보조 설정 자로 볼 수 있습니다.
업데이트 : 보너스로 겉보기에 혼란스럽고 제 생각에는 컴파일 오류가 다음과 같습니다.
접근 자의 내게 필요한 옵션 수정자는 Connection1.ConnectionString 속성보다 더 제한적이어야합니다.
실례 더 제한적인 것보다 private
, 어떻게 ... 어떻게?
명시 적 인터페이스 멤버 를 호출 하는 유일한 방법 은 개체를 올바른 인터페이스로 캐스팅 한 다음 해당 인터페이스에서 멤버를 호출하는 것입니다. 그러나 일단 캐스트하면 IConnection
에 IConnection.ConnectionString
세터가 없습니다.
따라서이 개인 setter 메서드 를 호출 할 방법 이 없습니다 .
문제는 인터페이스 멤버가 명시 적으로 선언 될 때 컴파일러 private
가 "발음 할 수없는"이름 으로 구현을 생성 하고 구현 클래스 내에서도 해당 구현을 참조하는 코드를 제공하지 않는다는 것입니다.
기본적으로라고 말할 때 하나는 클래스 범위 내에서 void IFoo.Moo()
이름을 정의하고 싶지 않다는 것입니다 Moo
. 결과적으로 컴파일러는 그렇지 않습니다. 위해서는 private set
하려면 회원은 "발음 할 수있는"이름을 명시 적으로 구현 된 회원이 하나가 이름이되고 싶어하지 않는 표시로 간주된다는 사실 할 것이다 Moo
.
실제로 여기서 해결 방법은 이름이 발음 가능하지만 이름으로 공개적으로 노출되지 않는 인터페이스 구현이 필요한 다른 많은 경우와 동일 할 것입니다. 다른 구성원에 연결하는 것 외에는 아무것도하지 않는 인터페이스 구현을 선언합니다. 적절한 액세스 가능성이 있습니다. 예를 들어 파생 클래스가 값에 영향을 줄 수없는 경우 :
private readonly int _foo = whatever;
public int IFOO.Foo { get {return _foo;}}
또는 파생 클래스가 영향을 미칠 수 있어야하는 경우
protected int _foo = whatever;
public int IFOO.Foo { get {return _foo;}}
또는
private int _foo = whatever;
protected virtual int setFoo(int value) { _foo = value; }
protected virtual int getFoo() { return _foo; }
public int IFOO.Foo { get {return getFoo();}}
vb.net에서 인터페이스는 보호 된 클래스 멤버를 사용하여 구현 될 수 있지만 C #은 이러한 기능을 제공하지 않습니다.
문제의 핵심은 인터페이스가 필요한 것만 가지고 있다는 것입니다. 공개되지 않은 경우 자연스럽게 인터페이스의 일부가 아닙니다. 따라서 인터페이스를 명시 적으로 구현하면 존재하지 않습니다.
암묵적인 경우 코드는 인터페이스에 맞지만 완전히 제한되지는 않습니다. 필요한 경우 더 많은 것을 추가 할 수 있습니다.
그 이유에 대한 정보를 얻으 려면 해당 언어의 디자이너가 답변해야합니다. 그러나 나에게는 논리적으로 보입니다 . 인터페이스의 일부가 아니면 인터페이스의 일부로 구현 / 액세스 할 수 없습니다.
The property declaration is an atomic thing containing a getter and a setter. It should match the interface.
If you would allow this, then apparently the getter and setter are seen as different things. In that case there is no use to limiting it to privates either. In that case the interface just dictates that there has to be a property which can be read, and you are free to make it writable as well.
Anyway, apparently it's a design decision to make it atomic.
Perhaps the explicit interface implementation should not be seen as part of the class itself but rather as a kind of adapter from your interface to the class. Given this view; consider the following implementation:
public interface I {
string S { get; set; }
}
class C : I {
public C() {
this.S = "Hello World";
//compile error: explicit implementation not accessible
}
string I.S { get; set; }
}
In class C, the property S is not even privately accessible because it is an explicit implementation. Would it not be bad design in the first place to have a concrete implementation of a field not be accessible by the implementation itself?
Furthermore, in your example creating a setter for the explicit implenentation would never be accessible; since the property is only accessible when cast to the IConnection
interface. There it only has a getter.
ReferenceURL : https://stackoverflow.com/questions/23611913/why-is-it-illegal-to-have-a-private-setter-on-an-explicit-getter-only-interface
'programing' 카테고리의 다른 글
Entity Framework 6에서 분리 된 엔터티 저장 (0) | 2021.01.14 |
---|---|
React : 키보드 이벤트 핸들러 모두 'Null' (0) | 2021.01.14 |
한 Git 저장소에서 다른 저장소로 커밋을 복사하는 방법은 무엇입니까? (0) | 2021.01.14 |
Uglify 구문 오류 : 예기치 않은 토큰 : punc ()) (0) | 2021.01.14 |
C # 목록 이해 소개 (0) | 2021.01.14 |