Kungani i-interface ingasebenzi kepha isigaba esingaqondakali sisebenza ngesithiyo seklasi ejwayelekile?

Ikhodi engezansi ikhombisa isigaba esijwayelekile esinenkinga yohlobo ( Pub ). Isigaba sinomcimbi esingawukhulisa esivumela ukuthi sidlulise umlayezo kubabhalisile. Isithiyo ukuthi umlayezo kufanele usebenzise i- IMsg (noma uzuze ifa kusuka ku- IMsg uma kuyisigaba esingaqondakali).

I-Pub futhi inikeza i- Bhalisa indlela yokuvumela izinto ukuthi zibhalise kumcimbi we- yazisa uma futhi kuphela uma into isebenzisa IHandler .

Usebenzisa i-. NET 4, ikhodi engezansi ikhombisa iphutha ku- baseImplementer.NotifyEventHandler esisho ukuthi:
"Akukho ukulayisha ngokweqile kwe-'Handler . I-NotifyEventHandler (IMsg) 'ifana nesithunywa' System.Action '"

Umbuzo: ( ngendlela ebhalisiwe yokubhalisa)

Kungani iphutha lihamba ngokushesha nje lapho ngishintsha u-`IMsg` ngibe isigaba esingaqondakali esikhundleni se-interface?

public interface IMsg { }        // Doesn't work
//public abstract class IMsg { } // Does work

public class Msg : IMsg { }

public class Pub<T> where T : IMsg
{
    public event Action<T> notify;

    public void Subscribe(object subscriber)
    {
        // Subscriber subscribes if it implements IHandler of the exact same type as T
        // This always compiles and works
        IHandler<T> implementer = subscriber as IHandler<T>;
        if (implementer != null)
            this.notify += implementer.NotifyEventHandler;
        // If subscriber implements IHandler<IMsg> subscribe to notify (even if T is Msg because Msg implements IMsg)
        // This does not compile if IMsg is an interface, only if IMsg is an abstract class
        IHandler<IMsg> baseImplementer = subscriber as IHandler<IMsg>;
        if (baseImplementer != null)
            this.notify += baseImplementer.NotifyEventHandler;
    }
}

public interface IHandler<T> where T : IMsg
{
    void NotifyEventHandler(T data);
}

Ikhodi engezansi lapha ayidingeki ukukhiqiza inkinga futhi ... kodwa ikhombisa ukuthi kanjani ikhodi engenhla ingasetshenziswa. Ngokusobala IMsg (kanye nezifundo ezitholakele Msg ) zingachaza noma zisebenzise izindlela ezingabizwa kumphathi.

public class SubA : IHandler<Msg>
{
    void IHandler<Msg>.NotifyEventHandler(Msg data) { }
}

public class SubB : IHandler<IMsg>
{
    void IHandler<IMsg>.NotifyEventHandler(IMsg data) { }
}

class MyClass
{
    Pub<Msg> pub = new Pub<Msg>();
    SubA subA = new SubA();
    SubB subB = new SubB();

    public MyClass()
    {
        //Instead of calling...
        this.pub.notify += (this.subA as IHandler<Msg>).NotifyEventHandler;
        this.pub.notify += (this.subB as IHandler<IMsg>).NotifyEventHandler;

        //I want to call...
        this.pub.Subscribe(this.subA);
        this.pub.Subscribe(this.subB);

        //...except that the Subscribe method wont build when IMsg is an interface
    }
}
12
задан Scott 30 June 2011 в 22:24
поделиться