2010-05-03 5 views
12

this Java question과 유사합니다. 여러 인터페이스를 구현하는 변수를 지정하고 싶습니다. 예를.Net에서 여러 인터페이스를 구현하는 변수를 선언하는 방법이 있습니까?

를 들어
private {IFirstInterface, ISecondInterface} _foo; 

public void SetFoo({IFirstInterface, ISecondInterface} value) 
{ 
    _foo = value; 
} 

요구 사항 :

  • 나는 푸에 전달 될 대부분의 유형에 대한 인터페이스를 추가 할 수있는 기능이 없습니다. 그래서 IFirstInterface 및 ISecondInterface에서 상속받은 세 번째 인터페이스를 만들 수 없습니다.
  • Foo의 유형이 클래스와 관련이 없으며 사용자가 컴파일 타임에이를 알지 못하기 때문에 가능하면 포함하는 클래스를 일반화하지 않는 것이 좋습니다.
  • 두 인터페이스의 메소드에 나중에 액세스하려면 foo를 사용해야합니다.
  • 컴파일러를 안전하게 사용하고 싶습니다. 즉, 인터페이스를 사용하려고하기 전에 인터페이스에 캐스트하지 않으려 고합니다. foo가 두 인터페이스를 모두 구현하지 않으면 꽤 많은 기능이 제대로 작동하지 않습니다.

이것은 가능합니까?

편집 : 저는 여러 가지 이유로이 작업을 몇 번하고 싶습니다. 이 인스턴스에서는 ObservableCollections에서 ReadOnlyObservableCollections로 속성 집합을 변경하기 때문입니다. 소스 ObservableCollection에서 다른 Collection으로 프로젝션을 만드는 도우미 클래스가 있습니다. ReadOnlyObservableCollection은 ObservableCollection에서 상속받지 않으며 IList 및 INotifyCollectionChanged에서만 작업이 필요하기 때문에 ObservableCollection을 필요로하지 않고 내 소스 컬렉션을이 두 인터페이스의 조합으로 저장하려고합니다.

+1

당신은 운이 있습니다. – ChaosPandion

+2

짧은 대답 : 아니오. IFirstInterface 및 ISecondInterface에서 상속 한 세 번째 인터페이스를 정의하지 않아도됩니다. – Anthony

+2

나의 유일한 생각은 두 개의 인터페이스 변수와 같은 인스턴스를 가질 수 있다는 것입니다. 이 상황이 필요한 상황은 무엇입니까? 이런 식으로 필요한 곳에서하고 있었던 일에 대해 통찰력을 줄 수 있습니까? –

답변

13

, 당신은 운 입니다 :이 시점에서

public void SetFoo<T>(T value) where T : IFirstInterface, ISecondInterface 
{ 
    _foo = value; 
} 

, 당신이 당신의 _foo에 액세스하려면 언제든지 멤버가이 두 인터페이스 중 하나 인 경우 캐스팅을 통해 액세스해야합니다 ((IFirstInterface)_foo 또는 (ISecondInterface)_foo).

컴파일 타임 안전을 위해 캐스트를 사용하지 않으려는 경우가 있습니다. 제 생각에는 _foo이 위의 SetFoo을 사용하여 초기화되도록하는 방법을 찾으면 원하는 모든 것을 마음대로 캐스팅 할 수 있습니다.


난 그냥 아래의 실현 특별히 당신이 가하고 싶지 않은 질문에 명시된 뭔가를 설명합니다.그래서 나는 위와 같이 말한다.

_foo 객체가 클래스 멤버 (I 변수 이름에 _에 이러한 가정을 내놓고있어),이 방법으로 클래스를 정의 할 수 있습니다처럼 보이는 때문에 또 다른 아이디어는 다음과 같습니다

class YourClassThatHasAFoo<T> where T : IFirstInterface, ISecondInterface { 
    private T _foo; 

    public void SetFoo(T value) { 
     _foo = value; 
    } 
} 

실제로 이것이 의미가 있는지 여부는 특정 시나리오에 따라 다릅니다. 이와 같은 제약 조건을 가진 클래스가 길 아래로 예상하지 못한 문제로 이어질 수 있으므로 (예 : SetFoo 의 매개 변수를 가져야 함) 귀하의 두 인터페이스).

+0

당신, 황금 쿠키를 가져와. 이 코드는 매우 유용합니다! –

+0

'(IFirstInterface) _foo'는 허약합니다. 'T'에 대한 제약 조건에서'IFirstInterface'를 제거하면 런타임 캐스트가됩니다. 하지만 할 수 있습니다.,'IFirstInterface _fooFirst = _foo' 또는 [컴파일 타임/정적 캐스트를 확실히하기 위해 다른 트릭을 사용하십시오] (http://stackoverflow.com/q/3894378/429091). – binki

2

.NET의 변수에는 유형이 있으며 유형은 여러 인터페이스를 구현할 수 있습니다. 이런 식으로 뭔가 :

public interface Interface1 { } 
public interface Interface2 { } 
public class SupportsMuliple : Interface1, Interface2 { } 

하지만 변수가 그 인터페이스를 구현하는 유형을하지 않고 여러 인터페이스를 구현하고 싶지 같은 질문에서 보인다. 이것은 실제로 가능하지 않지만 인터페이스를 구현하는 유형을 실시간으로 생성 할 수 있으며 실제 유형이 마법을 수행한다는 사실을 숨길 수 있습니다. 조롱 라이브러리 moqCastle DynamicProxy을 사용하여이 작업을 수행합니다. 이 두 인터페이스를 구현에만 매개 변수를 적용하려면 방법 SetFoo을 제한하려는 경우

+0

응답 해 주셔서 감사합니다. 인터페이스를 구현하는 유형은 이미 존재하며, 구현 방식에 상관없이이를 저장하고 사용하는 방법이 필요합니다. –

5

아니요, 특정 인스턴스가 둘 이상의 인터페이스를 구현한다는 것을 선언적으로 보장 할 방법이 없습니다.

하나의 옵션은 제네릭을 사용하여 가능할 수도 있지만 실제로는 속성이 아닌 함수에서만 작동합니다. 형식 유추를 사용

public void Foo<T>(T arg) 
    where T : IFirstInterface 
    where T : ISecondInterface 
{ 
    ... 
} 

, 당신은 다음과 같이 호출 할 수 있어야한다 :

ConcreteType bar = new ConcreteType(); // this implements both 

Foo(bar); 
1

그들의 임의의 조합이 필요하며, 형태 보증 방식으로 사용 할 수 있도록 인터페이스를 정의 할 수 있습니다 . 핵심은 인터페이스 ISelf (Of Out T)를 정의하는 것입니다.이 멤버의 자체 멤버는 자체가 T로 반환되는 속성이며 각 인터페이스 IFoo에 대해 IFoo (Of Out T)는 IFoo와 ISelf (Of T)를 상속받습니다. ISelf (Of Wowzo), IFoo (Of Wowzo), IBar (Of Wowzo), IBoz (Of Wowzo)를 구현하는 Wowzo 클래스는 IFoo (Of IBar), IBar (IFoo), IFoo (IBar) 중)))))))))))))))))))))))))))))))))))))))))))))))))))) Thing이 IFoo (IBar 중 Of IBoz) 인 경우 IFoo로 직접 사용하거나 Thing.Self를 IBar로 사용하거나 Thing.Self.Self를 IBoz로 사용할 수 있습니다. C 번호와 함께이 방법을 세 가지 인터페이스를 함께 구성하는 방법에

예 :

public interface ISelf<out T> 
{ 
    T Self { get; } 
} 
interface IA { } 
interface IA<T> : IA, ISelf<T> { } 
interface IB { } 
interface IB<T> : IB, ISelf<T> { } 
interface IC { } 
interface IC<T> : IC, ISelf<T> { } 
class ConcreteThing 
    : IA<ConcreteThing> 
    , IB<ConcreteThing> 
    , IC<ConcreteThing> 
{ 
    public ConcreteThing Self => this; 
} 
public class ReferencingObject 
{ 
    IA<IB<IC>> Thing { get; } 

    void Method() 
    { 
     IA a = Thing; 
     IB b = Thing.Self; 
     IC c = Thing.Self.Self; 
    } 
} 
관련 문제