关于.net:C#中的对象,参数和ref关键字

Objects, parameters and the ref keyword in C#

当方法的形参类型为"object"时,通过继承,实际参数可能是任何对象类型。在方法中,可以将对象强制转换为预期的类型。一切都很好。

但是,如果方法的签名有一个"object"的形式参数,使用ref关键字,即methodname(ref object),编译器将抛出一个错误,说明:

"与"ByRefTest.Program.ChangeMebyref(Ref Object)"匹配的最佳重载方法具有一些无效参数。"参数"1":无法从"ref byreftest.person"转换为"ref object"

在将对象作为参数传递时使用或不使用ref keword的区别在a.friedman的博客http://crazorsharp.blogspot.com/2009/07/passing-object s-using-ref-keywordwait.html中得到了很好的解释,但当类型"object"的形式参数使用ref k时,为什么不可能将自定义类型作为实际参数传递呢?EYWord?

举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Program
{
    static void Main(string[] args)
    {
        Person p = new Person();

        changeMe(p); // compiles
        changeMeByRef(ref p); // throws error

        object pObject = (object)p;
        changeMeByRef(ref pObject); // compiles
    }


    public static void changeMeByRef(ref object obj)
    {
        Person p = (Person)obj;
    }

    public static void changeMe(object obj)
    {
        Person p = (Person)obj;

    }
}

public class Person
{
}

谢谢。

我刚把签名改为:

public static void changemebyRef(ref t obj)其中t:person

这是为changemebyref(ref p)编译的;


因为方法可能会将参数更改为具有不同类型的值,这违反了用于参数的变量的类型。简单例子:

1
2
3
4
5
6
7
8
9
10
public void Foo(ref object x)
{
    x ="hello";
}

...

// This doesn't compile, fortunately.
Stream y = null;
Foo(ref y);

方法中的赋值后,y的值是多少?它应该是一个字符串,但这违反了变量的类型。那将是非常糟糕的事情,完全违反类型安全。即使在.NET 4.0中,这也是IList的一般不变性的一种原因。

埃里克·利珀特最近在博客中更详细地介绍了ref的不变性。


因为ref参数是双向工作的。可以将参数分配给函数内的任意对象,调用代码需要处理它。


EricLippert解释了为什么ref和out参数不允许类型变化?


这样做。这比较容易。changeme(p);//编译changemebyref(ref(object)p);//这次不应引发错误。