我有一个带有此签名的方法:
protected bool MyMethod (ref IMyInterface model) {
// stuff and things
}
我有一个模型,我从这个班级传入:
public class MyClass: IMyInterface {
// class stuff and things
}
我试图将我的模型传递给方法,如下所示:
var model = new MyClass():
MyMethod(ref model);
但是,我收到有关与参数类型不匹配的类型的错误。如果我不通过引用传递,它可以正常工作。或者,如果我投射它并像这样传递它,它工作正常。
var tempModel = (IMyInterface)model;
MyMethod(ref tempModel);
如果没有必要,我宁可避免演员表,但如果没有它,我也无法通过。我想如果类实现了接口,我可以传递模型。这不是我可以通过参考做的事情,还是我错过了什么?
答案 0 :(得分:14)
如果您不使用隐式类型,只需将变量定义为接口,它就会起作用:
IMyInterface model = new MyClass():
MyMethod(ref model);
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...
答案 1 :(得分:5)
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".
C#只是禁止使用ref
,但有一点" help"手动..
m = (MyClass)f; // "Trusting this is okay"
请参阅https://stackoverflow.com/a/2877515/2864740有关out
参数关键字的差异规则原因的更深入说明。
答案 2 :(得分:3)
你可以通过这样的泛型实现这一点:
public static class Disposable
{
public static void TryDisposeAndClear<T>(ref T obj) where T : IDisposable
{
try
{
obj.Dispose();
}
catch { }
obj = default(T);
}
}