我可以有一个接口参数,通过引用传递吗?
Can I have an interface parameter, pass by reference?
我有一个带有此签名的方法:
protected bool MyMethod (ref IMyInterface model) {
// stuff and things
}
我有一个从这个 class 传入的模型:
public class MyClass: IMyInterface {
// class stuff and things
}
我正在尝试将我的模型传递到方法中,如下所示:
var model = new MyClass():
MyMethod(ref model);
但是,我收到有关类型与参数类型不匹配的错误。如果我不通过引用,它工作正常。或者,如果我像这样投射并传递它,它就可以正常工作。
var tempModel = (IMyInterface)model;
MyMethod(ref tempModel);
如果没有必要,我宁愿避免强制转换,但没有它我无法通过。我想如果 class 实现了接口,我可以通过模型。这不是我可以通过参考做的事情还是我遗漏了什么?
ref
不能采用所请求类型的 子类型 (即 IMyInterface
),因为这样该方法就不能保证赋值不会违反调用者(即它想要 MyClass
)。因此使用 ref
(或 out
)需要 exact 类型。
这实际上是错误所在:
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"
请参阅 更深入地解释 out
参数关键字的变化规则的原因。
如果您不使用隐式类型,而只是将您的变量定义为接口,它将起作用:
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...
您可以像这样使用泛型实现此目的:
public static class Disposable
{
public static void TryDisposeAndClear<T>(ref T obj) where T : IDisposable
{
try
{
obj.Dispose();
}
catch { }
obj = default(T);
}
}
我有一个带有此签名的方法:
protected bool MyMethod (ref IMyInterface model) {
// stuff and things
}
我有一个从这个 class 传入的模型:
public class MyClass: IMyInterface {
// class stuff and things
}
我正在尝试将我的模型传递到方法中,如下所示:
var model = new MyClass():
MyMethod(ref model);
但是,我收到有关类型与参数类型不匹配的错误。如果我不通过引用,它工作正常。或者,如果我像这样投射并传递它,它就可以正常工作。
var tempModel = (IMyInterface)model;
MyMethod(ref tempModel);
如果没有必要,我宁愿避免强制转换,但没有它我无法通过。我想如果 class 实现了接口,我可以通过模型。这不是我可以通过参考做的事情还是我遗漏了什么?
ref
不能采用所请求类型的 子类型 (即 IMyInterface
),因为这样该方法就不能保证赋值不会违反调用者(即它想要 MyClass
)。因此使用 ref
(或 out
)需要 exact 类型。
这实际上是错误所在:
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"
请参阅 更深入地解释 out
参数关键字的变化规则的原因。
如果您不使用隐式类型,而只是将您的变量定义为接口,它将起作用:
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...
您可以像这样使用泛型实现此目的:
public static class Disposable
{
public static void TryDisposeAndClear<T>(ref T obj) where T : IDisposable
{
try
{
obj.Dispose();
}
catch { }
obj = default(T);
}
}