10

C#でこれが間違っている理由を誰かに説明してもらえますか:

namespace NamespaceA
{
    public class ClassA
    {
        public interface IInterfaceA
        {
            String Property
            {
                set;
            }
        }
    }
}

namespace NamespaceB
{
    public class ClassB
    {
        public class ImpA: NamespaceA.ClassA.IInterfaceA
        {
            private String mProperty;
            public String Property{ set{ mProperty = value; } }
        }
        public ClassB()
        {
            ImpA aImpA = new ImpA();
            foo(ref aImpA);
        }

        private void foo(ref NamespaceA.ClassA.IInterfaceA aIInterfaceA)
        {
            aIInterfaceA.Property = "SomeValue";
        }
    }
}

これにより、次のコンパイル エラーが発生します。

エラー引数 1: 'NamespaceB.ClassB.ImpA' から 'ref NamespaceA.ClassA.IInterfaceA' に変換できません

インターフェース プロパティを変更して、 からインターフェース関数を呼び出すことは、完全に理にかなっているように思えますfoo()。キーワードを削除するrefとコンパイルされますが、行った変更foo()は失われます...

4

2 に答える 2

15

Karthik が言ったように、オブジェクト指向ポリモーフィズムはサポートされていませんrefoutただし、ジェネリック (別名パラメトリックポリモーフィズム) を使用して同じ効果を得ることができます。

の署名を次のように変更してみてくださいfoo

private void foo<T>(ref T aIInterfaceA) 
    where T : NamespaceA.ClassA.IInterfaceA
{
    aIInterfaceA.Property = "SomeValue";

    // This assignment will be visible to the caller of foo
    aIInterfaceA = default(T);
}

おまけ— 必要に応じnew()て、型パラメーターに制約を設定してT、デフォルトのコンストラクターを呼び出すこともできます。

private void foo<T>(ref T aIInterfaceA) 
    where T : NamespaceA.ClassA.IInterfaceA, new()
{
    aIInterfaceA.Property = "SomeValue";

    // This assignment will be visible to the caller of foo
    aIInterfaceA = new T();
}
于 2015-11-25T23:42:54.277 に答える
0

まず、そこでrefキーワードを使用する必要はありません。

参照型のインスタンスをパラメーターとして渡しているので、引数をその状態(ここではプロパティref)を変更できるようにマークする必要はありません。キーワードをProperty削除するだけで、期待どおりに機能します。ref

第二に、考えてみてください。インターフェイスのインスタンスが参照型になるとすぐに、refパラメータによって渡される参照を変更できるため、理論的には、このインターフェイスのまったく異なる実装を返すことができます。

IInterfaceAしたがって、コードに必要な場合は、からへの暗黙のキャストはありませんImpA

于 2013-02-08T02:29:09.753 に答える