2012-04-28 3 views
0

인터페이스를 통해 통신하는 여러 클래스간에 메시지를 전달하려고합니다. 그러나 가능한 한 제네릭을 사용하고자 할 때 수신 메시지의 메시지 유형이 발신 유형과 다를 수 있으므로 문제가 발생했습니다. 나는 그것을 명확하게하기 위해 몇 가지 코드를 붙여 넣었다.일반 인터페이스 및 형식 구문 분석

인터페이스 구현이 들어오는 메시지를 추가하기로되어있는 차단 컬렉션의 형식과 다른 형식을 전달하기 때문에 아래 코드는 컴파일되지 않습니다. 들어오는 유형과 잠재적으로 다른 유형을 보낼 수 있기를 원합니다 (들어오는 유형은 항상 블로킹 콜렉션의 요소 유형과 일치합니다). 인터페이스 나 클래스를 다시 디자인해야하는 경우에도 캐스팅이나 파싱을 수행 할 수 있습니까?

인터페이스를 사용하여 작업 할 때 여전히 매우 신선하고 재귀, 스택 오버플로 오류 등으로 어려움을 겪습니다. 따라서, 현명한 디자인 또는 빠른 수정을 제안 할 수있는 제안이 있으면 배우십시오. 더 나은 패턴을 구현하는 방법을 알고 싶어합니다.

감사

public interface IClientMessaging 
{ 
    void MessagePassing<U>(U message); 
} 

public class InProcessMessaging<T> : IClientMessaging 
{ 
    private Dictionary<Type, List<IClientMessaging>> Subscriptions; 
    public BlockingCollection<T> MessageBuffer; 

    public InProcessMessaging(Dictionary<Type, List<IClientMessaging>> subscriptions) 
    { 
     //Setup Message Buffer 
     MessageBuffer = new BlockingCollection<T>(); 

     //Subscribe 
     Type type = typeof(T); 
     if (subscriptions.Keys.Contains(type)) 
     { 
      subscriptions[type].Add(this); 
     } 
     else 
     { 
      subscriptions.Add(type, new List<IClientMessaging>()); 
      subscriptions[type].Add(this); 
     } 

     Subscriptions = subscriptions; 
    } 

    public void SendMessage<U>(U message) 
    { 
     //Send message to each subscribed Client 
     List<IClientMessaging> typeSubscriptions = Subscriptions[typeof(U)]; 
     foreach (IClientMessaging subscriber in typeSubscriptions) 
     { 
      subscriber.MessagePassing<U>(message); 
     } 
    } 

    public T ReceiveMessage() 
    { 
     return MessageBuffer.Take(); 
    } 

    public bool ReceiveMessage(out T item) 
    { 
     return MessageBuffer.TryTake(out item); 
    } 

    //Interface Implementation 
    public void MessagePassing<U>(U message) 
    { 
     MessageBuffer.Add(message); //<-"Cannot convert from U to T" [this is because I want 
            //to send messages of a different type than the receiving type] 
    } 
} 
+1

'InProcessMessaging'은 모두'IClientMessaging'을 구현하고'IClientMessaging'의 가입자 목록을 관리하는 이유는 무엇입니까? –

답변

1

내가 여기 당신의 목표를 이해하는 데 어려움을 겪고있어, 그러나 아마 MessagePassing<U>(U message)MessagePassing(U message)해야하며 interface IClientMessaginginterface IClientMessaging<U>을해야합니다.

다음 InProcessMessaging<T, U> : IClientMessaging<U>

-하지만 InProcessMessagingIClientMessaging의 가입자 목록을 IClientMessaging를 구현하고 관리하는 이유는 표시되지 않습니다. 한 클래스가 가입자를 관리하고 다른 클래스가 가입자 (IClientMessaging)라고 나에게 들었다.

UT은 다른 유형입니다. 그게 관련이 있습니까? 다른 래퍼가 있습니까? 어쩌면 U 같은 소리는 T의 래퍼이거나 T을 포함하지만 추가 정보를 추가하는 일반 클래스 자체입니다. 이 경우, void MessagePassing<T>(Wrapper<T> message);

지금까지 의견을 갱신한다

...

interface IClientMessage {} 

interface IClientMessage<U> : IClientMessage { /* ... */ } 

그러나이에 그 이름을 변경 :

interface IConsumer {} // (Or ISubscriber?) 

interface IConsumer<TConsumed> : IConsumer{ /* ... */ } 

을 추가합니다 :

interface IGenerator { } 

interface IGenerator <TGenerated> : IGenerator { 
    event EventHandler<TGenerated> ItemGenerated; 
} 

그 다음 :

예, 이것은 리플렉션을 사용하여 IConsumer<TConsumed>.Consume()을 호출합니다. 또는 제네릭을 사용하지 말고 object을 유형으로 사용할 수 있습니다. 더 나아가서 IClientMessageConsume(object message) 일 수 있습니다. 구현시 처리하기 전에 objectTConsumed임을 보장 할 수 있습니다.

C# 이벤트를 통해 직접 클라이언트 - 클라이언트 링크를 만들 수는 있지만 중앙 디스패처에 대한 것 같습니다.중앙 처리자는 반사가 필요하거나 전달되는 유형을 알지 못하는 유형의 다양하고 제한되지 않은 유형을 추적해야합니다 (이전 단락에서 설명한대로)

Reactive Extensions과 아이디어를위한 관찰자 패턴.

너무 수다스러운 댓글을 삭제했습니다.

+0

나는 당신의 아이디어가 반성을 얻지 못한다고 생각합니까? 나는 강력한 타이핑을 고수하는 해결책을 찾는다. 나는 당신의 대답이 그것을 다루는지를 보지 못한다. 내가 틀렸다면 나를 바로 잡아주세요. 설명 된 메시지는 블로킹 컬렉션에 전달 된 유형 안전 형일 수 있으므로 인터페이스를 사용하는 것에 대해 생각한 유일한 이유는 특정 클라이언트 유형에 일치하는 블로킹 콜렉션을 구현 한 일치하는 클라이언트에 특정 메시지 유형을 전달하기 위해 모든 클라이언트/메시지 수신자를 하나의 콜렉션에 보관하는 것이 었습니다. 유형. 어떤 상황에서도 강력한 타이핑을 포기하고 싶지 않습니다. –

+1

아니요. 당신이'is'와'as'를 좋아하지 않는다면 말입니다. 나는 "더 나은 아직"부분이 반사를 피한다고 생각한다. –

+0

uosɐs, 시간을 내 주셔서 감사합니다. 나는 당신의 아이디어로 생각하고 노는 시간을 보냈다. 나는 정적 클래스에서 특정 유형을 보유하고있는 컬렉션을 차단하는 저장소를 설치하고 직접 액세스 할 수 있다고 생각한다. 동일한 컬렉션에 동시에 추가하는 클라이언트가 둘 이상 존재하지 않으며 하나의 주어진 차단 컬렉션에서 하나 이상의 클라이언트를 사용하지 않기 때문에 그렇게 할 여유가 있습니다. 당신의 솔루션은 우아 해 보이지만 동시에 다른 유형의 콜렉션을 처리하려는 단순한 문제를 해결하기 위해 너무 복잡해 보입니다. –

관련 문제