Hans의 답변에 비추어 새로운 답변
Hans의 답변 덕분에 구현이 생각보다 다소 복잡하다는 것을 알 수 있습니다. 컴파일러와 CLR 모두 배열 유형이 구현하는 인상을주기 위해 매우 열심히 노력 IList<T>
하지만 배열 분산으로 인해이 작업이 더 까다로워집니다. 특정 배열의 유형이 있기 때문에 한스의 대답과는 달리, 배열 유형 (어쨌든, 제로, 하나의 차원은), 직접 제네릭 컬렉션을 구현합니까 하지 않습니다 System.Array
단지의 그 - 염기 배열의 유형입니다. 배열 유형에 지원하는 인터페이스를 묻는 경우 일반 유형이 포함됩니다.
foreach (var type in typeof(int[]).GetInterfaces())
{
Console.WriteLine(type);
}
산출:
System.ICloneable
System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]
1 차원, 0 기반 배열의 경우 언어 에 관한 한 배열도 실제로 구현 IList<T>
됩니다. C # 사양의 섹션 12.1.2는 그렇게 말합니다. 따라서 기본 구현이 무엇을하든, 언어는 다른 인터페이스와 마찬가지로 구현 유형이 작동 해야합니다 . 이러한 관점에서 인터페이스 는 명시 적으로 구현되는 일부 멤버 (예 :)로 구현됩니다 . 그것이 무슨 일이 일어나고 있는지에 대한 언어 수준 에서 가장 좋은 설명 입니다.T[]
IList<T>
Count
이것은 1 차원 배열 (및 0부터 시작하는 배열에만 적용되며, 언어로서의 C #이 0이 아닌 배열에 대해 아무 말도하지 않음)에만 적용됩니다. 구현 T[,]
하지 않습니다IList<T>
.
CLR 관점에서 보면 좀 더 펑키 한 일이 벌어지고 있습니다. 일반 인터페이스 유형에 대한 인터페이스 매핑을 가져올 수 없습니다. 예를 들면 :
typeof(int[]).GetInterfaceMap(typeof(ICollection<int>))
다음의 예외를 제공합니다.
Unhandled Exception: System.ArgumentException: Interface maps for generic
interfaces on arrays cannot be retrived.
그렇다면 왜 이상한가요? 글쎄요, 저는 그것이 실제로 배열 공분산 때문이라고 생각합니다. 이것은 타입 시스템 IMO에서 사마귀입니다. 비록 IList<T>
입니다 하지 (안전하게 할 수 없다) 공변, 배열 공분산 작업이 할 수 있습니다 :
string[] strings = { "a", "b", "c" };
IList<object> objects = strings;
... 이것은 실제로 그렇지 않은 경우 구현 처럼 보입니다 .typeof(string[])
IList<object>
CLI 사양 (ECMA-335) 파티션 1, 섹션 8.7.1에는 다음이 포함됩니다.
서명 유형 T는 서명 유형 U와 호환되며 다음 중 하나 이상이 유지되는 경우에만 가능합니다.
...
T는 0부터 1 등급 배열 V[]
하고 U
있다 IList<W>
, 그리고 V는 W.와 배열 요소 호환-IS
(실제로 사양에서 버그라고 생각 ICollection<W>
하거나 언급하지 않습니다 IEnumerable<W>
.)
비 변이의 경우 CLI 사양은 언어 사양과 직접 함께 진행됩니다. 파티션 1의 8.9.1 섹션에서 :
또한 요소 유형이 T 인 생성 된 벡터는 인터페이스를 구현합니다 System.Collections.Generic.IList<U>
. 여기서 U : = T입니다. (§8.7)
( 벡터 는 밑이 0 인 1 차원 배열입니다.)
지금의 관점에서 구현 세부 사항 , 명확하게 CLR 여기에 할당 호환성을 유지하기 위해 몇 가지 펑키 매핑을하고있다 : A는 때 string[]
의 이행을 요구한다 ICollection<object>.Count
, 그것은에 그것을 처리 할 수없는 매우 일반적인 방법. 이것이 명시 적 인터페이스 구현으로 간주됩니까? 인터페이스 매핑을 직접 요청하지 않는 한 언어 관점에서 항상 그렇게 행동 하기 때문에 그렇게 처리하는 것이 합리적이라고 생각합니다 .
어때 ICollection.Count
?
지금까지 제네릭 인터페이스에 대해 이야기했지만 속성이 있는 비 제네릭 ICollection
이 Count
있습니다. 이번에 는 인터페이스 매핑을 얻을 수 있으며 실제로 인터페이스는 System.Array
. 의 ICollection.Count
속성 구현에 대한 설명서 Array
에는 명시 적 인터페이스 구현으로 구현되었다고 명시되어 있습니다.
이런 종류의 명시 적 인터페이스 구현이 "일반적인"명시 적 인터페이스 구현과 다른 방식을 누구나 생각할 수 있다면 더 자세히 살펴 보겠습니다.
명시 적 인터페이스 구현에 대한 이전 답변
배열에 대한 지식으로 인해 더 복잡한 위의 내용에도 불구하고 명시 적 인터페이스 구현을 통해 동일한 가시적 효과로 작업을 수행 할 수 있습니다 .
다음은 간단한 독립 실행 형 예제입니다.
public interface IFoo
{
void M1();
void M2();
}
public class Foo : IFoo
{
// Explicit interface implementation
void IFoo.M1() {}
// Implicit interface implementation
public void M2() {}
}
class Test
{
static void Main()
{
Foo foo = new Foo();
foo.M1(); // Compile-time failure
foo.M2(); // Fine
IFoo ifoo = foo;
ifoo.M1(); // Fine
ifoo.M2(); // Fine
}
}
Array
클래스가 C #으로 작성되어야 한다고 말하지 않았습니다 !