c# - 通过 ref : cannot convert from 'Foo' to 'ref IFoo' 传递实现

标签 c# interface reference argument-passing

<分区>

有人可以向我解释为什么这在 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";
        }
    }
}

这将产生一个编译错误:

Error Argument 1: cannot convert from 'NamespaceB.ClassB.ImpA' to 'ref NamespaceA.ClassA.IInterfaceA'

想要修改接口(interface)属性并从foo() 调用接口(interface)函数似乎是完全合理的。如果您删除 ref 关键字,它会编译,但您在 foo() 中所做的更改将丢失...

最佳答案

正如 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);
}

Bonus — 如果需要,您可以在类型参数 T 上放置一个 new() 约束,然后它甚至可以让您调用它的默认构造函数:

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();
}

关于c# - 通过 ref : cannot convert from 'Foo' to 'ref IFoo' 传递实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14764649/

相关文章:

.net - 如何找出.NET函数可能引发的异常?

javascript - 复制对 native JavaScript 方法的引用是否安全?

c# - 如何以编程方式诊断原因、修复或解决与 Adob​​e ActiveX/COM 相关的错误 0x80004005?

c# - 通用 Windows 平台 (UWP) 相当于获取主应用程序 UI

java - jxl API : why writablesheet is an interface?

java - Android:将Closeable接口(interface)与Socket一起使用时出现异常

c# - 检索 asp :TextBox 的值

c# - 修剪盐的安全风险

go - 重新输入代码但保留现有界面

PHP变量访问数组中的变量