6

さて、これが私がやりたいことです。

Class Container<T>
{
    T contained;
    public void ContainObject(T obj)
    {
        contained = obj;
        if(/*Magical Code That Detects If T Implemtns IContainableObject*/)
        {
            IContainableObect c = (IContainableObject)obj;
            c.NotifyContained(self);
        }
    }
}

interface IContainableObject
{
    public void NotifyContained(Container<REPLACE_THIS>);//This line is important, see below after reading code.
}



Class ImplementingType : IContaiableObject
{
    public Container<ImplementingType> MyContainer;
    public void NotifyContained(Container<ImplmentingType> c)
    {
        MyContainer = c;
    }
}




Class Main
{
    public static void Main(args)
    {
        ImplementingType iObj = new ImplementingType();
        Container<ImplementingType> container = new Container();
        container.ContainObject(iObj);
        //iObj.MyContainer should now be pointing to container.
    }
}

基本的に、上記の例を要約すると、タイプTの汎用ラッパータイプがあります。含まれているオブジェクトが特定のインターフェース(このビットは私が行う方法を知っています)

しかし、それはトリッキーになります!なんで?コンテナジェネリックには型が必要だからです。

その重要な行を覚えていますか?

REPLACE_THISがIContainableObjectの場合、インターフェイスのすべての実装者は、NotifyContainedメソッドの実装クラスの名前ではなく、IContainerObjectを使用する必要があります。

明らかな理由から、インターフェイス内のコンテナのタイプとしてImplementingTypeを使用すると、さらに悪化します。

だから私の質問は、REPLACE_THISがインターフェースを実装するオブジェクトのクラスを表すようにするにはどうすればよいですか?

4

2 に答える 2

4
class Container<T>
{
    T contained;
    public void ContainObject(T obj)
    {
        contained = obj;
        var containable = obj as IContainableObject<T>;
        if(containable != null)
        {
            containable.NotifyContained(this);
        }
    }
}

interface IContainableObject<T>
{
    void NotifyContained(Container<T> c);
}

class ImplementingType : IContainableObject<ImplementingType>
{
    public Container<ImplementingType> MyContainer;
    public void NotifyContained(Container<ImplementingType> c)
    {
        MyContainer = c;
    }
}

編集:一般的な制約のあるバージョンを追加

interface IContainer<T>
{
    void ContainObject(T obj);
}

class Container<T> : IContainer<T> where T : IContainableObject<T>
{
    T contained;

    public void ContainObject(T obj)
    {
        contained = obj;
        contained.NotifyContained(this);
    }
}

interface IContainableObject<T>
{
    void NotifyContained(IContainer<T> c);
}

class ImplementingType : IContainableObject<ImplementingType>
{
    public IContainer<ImplementingType> MyContainer;

    public void NotifyContained(IContainer<ImplementingType> c)
    {
        Debug.WriteLine("notify contained");
        MyContainer = c;
    }
}
于 2012-05-19T20:38:38.873 に答える
1

すでに知っているかもしれませんが、このようにクラスを宣言できるのでIContainableObjects許可されている場合のみT

class Container<T> 
    where T : IContainableObject
{
    public void ContainObject(T obj)
    {
        // Here you know that obj does always implement IContainableObject.
        obj.NotifyContained(this);   
    }

    ...
}
于 2012-05-19T20:55:31.963 に答える