2009-03-04 17 views
2

友情がカプセル化を解除するかどうか議論してみましょう。実際に優雅にまとまったデザインを試してみましょう。これは、2倍の関数である:実装方法のC#でフレンド(C++で利用可能)を実装する

1)一般的な質問:

public class A 
    { 
     friend class B; 
    } 


2)なぜ私はこの機能が必要なのでしょうか?いくつかのクラスはISerializableインターフェイスを実装しています。しかし、私はISerializableメソッドをDerivedクラスで保護して、クライアントに(ドキュメンテーションと同様に)公開しないようにします。しかし、内部クラスはそれらにアクセスできる必要があります。 C#でこの問題を解決する一般的な方法は何ですか?

注:現在のC++標準で定義されているように友情を使用しています。同じアセンブリ内の他のタイプの型が内部にマーク表示されるように

おかげ

答えて

1

それはインターフェースを実装するに来るとき、あなたは唯一の2つの選択肢があります。

  • 明示的なインターフェイスの実装に

を使用してそれらを実装publicメソッド

  • でそれらを実装しますどちらの場合でも誰でもメソッドを呼び出すことができますが、明示的なインターフェイスの実装を使用すると、インターフェイス式を介してメソッドを呼び出すことしかできません(たとえば、実際のタイプの変数を)。

    「内部的に」インターフェイスを実装するという概念はありません。

  • +0

    これは私の考えです...しかし、議論のために、インターフェイス実装方法を内部としてマークしようとするとどうなりますか? –

    +0

    これはインタフェースを実装しなくなり、コンパイル時エラーが発生します。私の答えが実際に問題に対処していることを考えれば、なぜ私の答えが下落したのか分かりません。 –

    +0

    Jon、あなたは質問の最初の部分を解決しました - これは、クライアントがメソッドを呼び出さないようにします。 2番目の部分:私はこのメソッドをパブリックにしないでください。それ以外の場合は、doxygenはドキュメンテーションにエクスポートして、APIのユーザーを混乱させます。私はあなたに議決権を与えた –

    4

    C#が、internalキーワードを持っています。さらに、attributesをアセンブリに追加して、アセンブリの外部の型がアセンブリの内部メンバを参照できるようにすることもできます。

    +0

    例を挙げてください。この設計の目的は、このメソッドの存在についてCLIENTが何も知らないことを確認することです。 –

    +0

    クライアントは常にリフレクションを使用してあらゆる方法を検出できます。 –

    0

    internalメンバーは、現在の.dll内および外部で公開されています。さらに、InternalsVisibleTo属性を使用すると、外部.dllにそれらを公開することができます。

    4

    クラスが同じアセンブリ内にある場合は、internalを使用できます。異なるアセンブリにいる場合はfriend assembly attributeを使用できます。片側にInternalsVisibleToものを残し

    +0

    これは良いです!ありがとう... –

    0

    私は、発信者が誰であるかを証明するための秘密シングルトンインスタンスを「キー」として使用して、いくつかの解決策を示しています。

    解決方法1:フレンドクラスはシングルトン

    public class A 
    { 
        private underwear myUnderwear; 
    
        public ChangeUnderwear(B friend, underwear newUnderwear) 
        { 
        if (friend == null) return; 
        myUnderwear = newUnderwear 
        } 
    } 
    
    public sealed class B 
    { 
        private B() {}; 
        private B inst; 
        private MessWithA(A a) 
        { 
        a.ChangeUnderwear(this, new Thong()); 
        } 
    } 
    

    誰もが任意の欠陥を参照していますか?このテクニックは、FooクラスとFooManagerシングルトンがある場合に機能します。

    解決方法2: 友人がシングルトンでない場合、私はあなたが建設を隠し、すべてのインスタンス隠れの同じ考え使用することができます推測:

    interface IB 
    { ... } 
    
    public sealed class B : IB 
    { 
        private B() {}; 
        public IB CreateB() 
        { 
        return (IB)new B(); 
        } 
        private MessWithA(A a) 
        { 
        a.ChangeUnderwear(this, new Thong()); 
        } 
    } 
    

    をしかし、今あなたが今、あなたが防ぐために、いくつかの方法が必要ですIBをBにキャスティングするだけで敵を倒し、Aの友だちのみのメンバーにアクセスするためにBを偽装します。何か案は?

    解決方法3:シングルトンクラスを使用すると、インスタンスを要求した最初の呼び出し元がそのインスタンスを所有できるようになります。友人クラスは起動時にインスタンスを取得しようとし、他の誰かが最初にそれをつかんだ場合には怒りを吹き飛ばします。

    関連する問題