我在传递对泛型类型的对象的引用时遇到了一些麻烦。我找到了一种方法,创建一个'对象'并传递一个引用而不是原始的 - 但它似乎闻到了一点我。这里有更好的方法,还是我必须忍受它?
我理解第一个错误,但第二个错误让我失望。
public static T Foo<T>(ref T Bar)
{
T Result;
// Next line gives
// cannot convert from 'ref T' to 'ref object'
Result = (T)ModifyObject (ref Bar);
// Next line gives
// A ref or out argument must be an assignable variable
Result = (T)ModifyObject (ref ((Object)Bar) );
// Works
Object Tmp = Bar;
Result = (T)ModifyObject (ref Tmp) );
return Result;
}
public static Object DoSomthing(ref Object Obj) {
Object Result = Activator.CreateInstance (Obj.GetType ())
//...
}
DoSomething不是通用的,因为它使用Obj类型可以改变的递归。我试图不使用反射来调用它的泛型版本,虽然在发布时可能会有更好的选择吗?
答案 0 :(得分:5)
ref
参数的类型应与参数的类型匹配。您不能在此处依赖隐式转换。 Eric Lippert有一篇相关的博文:Why do ref and out parameters not allow type variation?
答案 1 :(得分:3)
第二条错误消息已包含解释:
ref或out参数必须是可赋值变量
就是这样:通过强制转换创建新对象:(Object) bar
可以引用相同的底层对象,但它仍然是一个不同的值。此外,它是临时值,因为您从未将其分配给不同的变量名称。因此,通过引用传递它是没有意义的 - 对该临时对象的任何更改都将丢失。因此,临时性是严格的右值:你不能分配它们,或通过引用传递它们。
这也是你的第三个代码有效的原因:你现在已经将转换的结果绑定到一个新名称,这个名字可以用作左值,即它可以被改变(分配给,通过引用传递)。
答案 2 :(得分:0)
对于第二个示例,您需要首先将其强制转换为对象变量:
object obj = (object)Bar;
Result = (T)ModifyObject (ref obj);
但是在执行该方法之后,唯一可以肯定的是obj
将是Object
类型。这就是编译器警告你的事情。
代码 闻到了一点味道。如果要返回类型为T的结果,那么我没有看到通过引用传递参数的原因。其次,您不需要通过引用传递类型的实例来创建它。这种方法可以正常工作:
public static Object DoSomething(Type objType) {
Object Result = Activator.CreateInstance(objType)
}
最后,如果你使用泛型,那么就没有理由进行所有的转换。 正是为什么您正在使用通用参数,以使您的类成为不同类型的模板。