4

私はライブラリを書いていて、インターフェースが欲しい

public interface ISkeleton
{
    IEnumerable<IBone> Bones { get; }
    void Attach(IBone bone);
    void Detach(IBone bone);
}

実際には、Attach() と Detach() の実装はすべての ISkeleton で同じでなければなりません。したがって、本質的には次のようになります。

public abstract class Skeleton
{
    public IEnumerable<IBone> Bones { get { return _mBones; } }

    public List<IBone> _mBones = new List<IBone>();

    public void Attach(IBone bone)
    {
         bone.Transformation.ToLocal(this);
         _mBones.add();
    }

    public void Detach(IBone bone)
    {
        bone.Transformation.ToWorld(this);
         _mBones.Remove(bone);
    }
}

しかし、C# では多重継承が許可されていません。そのため、さまざまな問題の中で、ユーザーは Skeleton を実装するたびに Skeleton から継承することを覚えておく必要があります。

拡張メソッドを使用できます

public static class Skeleton
{   
    public static void Attach(this ISkeleton skeleton, IBone bone)
    {
         bone.Transformation.ToLocal(skeleton);
         skeleton.Bones.add(bone);
    }

    public static void Detach(this ISkeleton skeleton, IBone bone)
    {
        bone.Transformation.ToWorld(this);
         skeleton.Bones.Remove(bone);
    }
}

しかし、私は持っている必要があります

public interface ISkeleton
{   
    ICollection<IBone> Bones { get; }
}

共変ではなく、ユーザーが Attach() および Detach() メソッドをバイパスできるため、これは望ましくありません。

質問: 本当に抽象 Skeleton クラスを使用する必要がありますか、それともトリックやメソッドはありますか?

4

5 に答える 5

5

Attachインターフェイスでメソッドとメソッドを公開する必要がある場合Detach、インターフェイスを実装するすべてのオブジェクトが独自のスタイルでそれらを実装できるため、意図した実装をバイパスする方法が常にあります。

Skeleton抽象クラスに実装させることができ、ISkeletonスケルトンであるすべてのクラスは から継承するSkeletonため、同様に実装さISkeletonれます。

public interface ISkeleton { ... }

public abstract class Skeleton : ISkeleton { ... } // implement attach and detach

public class SampleSkeleton : Skeleton { ... }

このようにSampleSkeletonasを使用できます。メソッドを継承し、メソッドを as としてマークしてもオーバーライドできない限り (インスタンス メソッドである限り)、ISkeletonこれらの関数を実装する必要はありません。Skeletonsealed

サイド ノード: 抽象クラスの名前をBase最後に付けるか、別の方法で基本クラスにマークを付けます (ただし、これは確かにあなた次第です)。

于 2012-04-18T13:11:55.013 に答える
3

ボーンを実装する特別なタイプにしますIEnumerable<T>。そうすれば、単一責任の原則に違反することはありません。

public interface ISkeleton
{
    AttachableEnumerable<IBone> Bones { get; }
}

public class AttachableEnumerable<T> : IEnumerable<T>
{
    // implementation needed.
    void Attach(T item);
    void Detach(T item);
}
于 2012-04-18T13:13:28.507 に答える
1

動作をラップしたい場合はISkeleton、動作を継承する代わりに、いつでも複合オブジェクトにすることができます。

public class Body : ISkeleton
{
    private SkeletonImpl _skeleton = new SkeletonImpl;

    public IEnumerable<IBone> Bones { get { return _skeleton.Bones; } }

    public void Attach(IBone bone)
    {
        _skeleton.Attach(bone);
    }

    public void Detach(IBone bone)
    {
       _skeleton.Detach(bone);
    }
}
于 2012-04-18T13:18:55.143 に答える
0

抽象 Skeleton クラスでシールされたメソッドを使用する必要があるだけでしょうか? このようにして、それらをオーバーライドすることはできません。

http://msdn.microsoft.com/en-us/library/aa645769(v=vs.71).aspx

于 2012-04-18T13:16:10.133 に答える
0

「アタッチ」および「デタッチ」メソッドを実装するラッパー クラスを作成し、この機能をインターフェイスに注入できます。

于 2012-04-18T13:22:59.997 に答える