我正在研究一种演示方法并发现一些奇怪的东西(至少对我来说: - ))
enter code here class Program
{
public void AnotherSwap<T>(T a, T b)
{
T temp;
temp = a;
a = b;
b = temp;
Console.WriteLine(a);
Console.WriteLine(b);
}
public void swap<T>(T a, T b) where T : MyInt // Passing without ref
{
object temp;
temp = a.MyProperty;
a.MyProperty = b.MyProperty;
b.MyProperty = (int)temp;
Console.WriteLine(a.MyProperty);
Console.WriteLine(b.MyProperty);
}
static void Main(string[] args)
{
Program p = new Program();
MyInt a = new MyInt() { MyProperty = 10 };
MyInt b = new MyInt() { MyProperty = 20 };
p.swap<MyInt>(a, b);
Console.WriteLine(a.MyProperty); // changed values get reflected
Console.WriteLine(b.MyProperty); // changed values get reflected
Console.WriteLine("Another Swap");
object x = 10;
object y = 20;
p.AnotherSwap(x, y);
Console.WriteLine(x); // changed values are not getting reflected
Console.WriteLine(y); // changed values are not getting reflected
Console.ReadKey();
}
public class MyInt
{
public int MyProperty { get; set; }
}
}
这里当我调用swap()时,虽然我没有提到ref,但是更改后的值会自动反映出来(如p.swap(a,b); a和b是Myint的实例,因此会根据我的理解,默认情况下作为参考。) 但同样的情况应该发生在Anotherswap()这里我也传递对象x,y但现在这些值没有反映在Main().i.e中。现在它作为一种价值类型。 有人可以解释我的理解是错误的。 如果你们想要更多信息,请告诉我。
答案 0 :(得分:3)
您的问题具有误导性,答案实际上比这简单:
在Swap函数中,您将交换这些类中的MyProperty属性的值,而不是实际的类本身。如果你在MyInt类中有另一个名为“Name”的属性,那么很容易证明这一点。在调用Swap之后,您会看到Name属性保持不变。
在AnotherSwap中没有发生任何有趣事情的原因是因为你根本没有通过ref传递类型,所以你对函数内对象指针执行的赋值不会修改原始对象的指针。来电者的观点。
要考虑的其他事情是,当你将10变成一个物体时,你实际上正在装箱,这是你需要记住的其他东西。在编写泛型时,您希望对于引用与值类型的行为不同,我总是只使用“where T:class”作为引用类型,使用“where T:struct”作为值类型。但这两个函数的名称不能相同。
答案 1 :(得分:1)
当MyInt类型被转换为Object时,它将被转换为val类型。对象不能像引用一样对待,因为它表示val和ref,它必须由ref。
显式传递int可以作为对象进行转换,并且仍然将其视为val。 string可以作为对象进行转换,并将其视为val。即使通常它会是ref类型。
如果您使用了AnotherSwap并将T in作为MyInt传递,您将获得与以前相同的结果。如果使用对象调用原始交换算法,则会得到与后者相同的输出。
答案 2 :(得分:1)
第二组对象[object x = 1
]被转换为int,这是一个值类型,因为它在初始化时被赋予了一个int,所以它被视为int
这是一个值类型
如果您运行以下代码段,您会看到我的观点。
object test = 1;
Console.Writeline(test.GetType());
returns: "typeof (Int32)"
所以object
的类型不再是对象,而是Int32,它是一种值类型。
object test = 1;
Console.Writeline(test.GetType().IsByRef);
returns: "false"