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)
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
参数关键字的方差规则的原因.