我可以有一个接口参数,通过引用传递?

Yat*_*rix 2 c# interface pass-by-reference

我有一个带有此签名的方法:

protected bool MyMethod (ref IMyInterface model) {
    // stuff and things
}
Run Code Online (Sandbox Code Playgroud)

我有一个模型,我从这个类传入:

public class MyClass: IMyInterface {
    // class stuff and things
}
Run Code Online (Sandbox Code Playgroud)

我正试图将我的模型传递给方法,如下所示:

var model = new MyClass():

MyMethod(ref model);
Run Code Online (Sandbox Code Playgroud)

但是,我收到有关与参数类型不匹配的类型的错误.如果我没有通过引用传递,它工作正常.或者,如果我投射它并像这样传递它,它工作正常.

var tempModel = (IMyInterface)model;

MyMethod(ref tempModel);
Run Code Online (Sandbox Code Playgroud)

如果没有必要,我宁愿避免演员,但如果没有它,我就无法通过.我想如果类实现了接口,我可以传递模型.这不是我可以通过参考做的事情,还是我错过了什么?

Ree*_*sey 15

如果您不使用隐式类型,只需将变量定义为接口,它将起作用:

IMyInterface model = new MyClass():

MyMethod(ref model);
Run Code Online (Sandbox Code Playgroud)

传递的参数ref必须与类型完全匹配,因为它们可以在方法中重新分配给与该协定匹配的另一种类型.在您的情况下,这将无法正常工作.想象一下:

protected bool MyMethod (ref IMyInterface model) 
{
    // This has to be allowed
    model = new SomeOtherMyInterface();
}

// Now, in your usage:
var model = new MyClass(); // Exactly the same as MyClass model = new MyClass();

MyMethod(ref model); // Won't compile...

// Here, model would be defined as `MyClass` but have been assigned to a `SomeOtherMyInterface`, hence it's invalid...
Run Code Online (Sandbox Code Playgroud)


use*_*740 6

ref不能采用所请求类型的类型(即.IMyInterface),因为这样的方法不能保证赋值不会违反调用者(即它想要一个MyClass).因此使用ref(或out)需要确切的类型.

这实际上是错误:

MyClass m = new MyClass();
IMyInterface f = m; // Okay: "m is IMyInterface"

MyMethod(ref f);    // Okay
m = f;              // Illegal: can't guarantee "f is MyClass".
Run Code Online (Sandbox Code Playgroud)

C#只是禁止这样做ref,虽然手动有点"帮助"..

m = (MyClass)f;     // "Trusting this is okay"
Run Code Online (Sandbox Code Playgroud)

请参阅/sf/answers/201426081/,更深入地解释out参数关键字的方差规则的原因.