是否可以在C#中不使用ref / out关键字交换两个变量(即使用unsafe)?
为前,
swap(ref x,ref y);//It is possbile to by passing the reference
但是,还有其他方法可以做同样的事情。在交换函数中,您可以使用临时变量。但是,如何在不使用C#中的ref / out关键字的情况下交换变量?
答案 0 :(得分:4)
使用代表的一个(非常!)人为的例子:
class Program
{
static void FunkySwap<T>(T a, T b, Action<T> setA, Action<T> setB)
{
T tempA = a;
setA(b);
setB(tempA);
}
static void Main(string[] args)
{
string s1 = "big";
string s2 = "apples";
Console.WriteLine("BEFORE, s1: {0}, s2: {1}", s1, s2);
FunkySwap(s1, s2, a => s1 = a, b => s2 = b);
Console.WriteLine("AFTER, s1: {0}, s2: {1}", s1, s2);
}
}
虽然上面的内容非常愚蠢,但使用委托setter方法在其他情况下非常有用;我已经使用该技术来实现属性修改的撤销/重做。
答案 1 :(得分:2)
不,如果没有使用传递引用,就不可能影响调用者中的变量*。你可能会影响班级成员,但是你怎么知道你被要求交换哪些?ref
或out
*(您可以影响引用类型的实例,并且调用者可以看到更改,但实例不是“变量”。)
答案 2 :(得分:1)
不是真的,除非您对ref
的唯一问题是不喜欢这个词本身。
您可以通过指针交换,例如:
public unsafe void Swap(int* x, int* y)
{
unsafe
{//lets not use a temp, just to be different!
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}
但实际上唯一的实际区别是引用的所有指针陷阱都会使您免于死亡,以及它必须是不安全的。它基本上做同样的事情。
答案 3 :(得分:1)
我试过这个
class Program
{
static void Main(string[] args)
{
int x = 3;
int y = 6;
Console.Write(string.Format("before swap x={0} y={1}", x, y));
Swap(x, y);
Console.Write(string.Format("after swap x={0} y={1}", x, y));
Console.ReadKey();
}
static public unsafe void Swap(int a, int b)
{
int* ptrToA = &a;
int* ptrToB = &b;
int c = a;
*ptrToB = c;
*ptrToB = *ptrToA;
}
}
完全忘记了int
是按值传递的,并且我无法从调用者到被调用者堆栈中获取实际COPIED的指针。
所以它不起作用
所以看起来,我不是更聪明,而是浪费了一些时间但是想与你分享:)
答案 4 :(得分:0)
您可以传递对象中的值,并返回该对象的实例,其值为swapped:
public struct Swapable
{
public int A;
public int B;
}
public Swapable Swap(Swapable swapable)
{
return new Swapable()
{
A = swapable.B;
B = swapable.A;
};
}
答案 5 :(得分:0)
我尝试过使用不安全的方法并且有效,请参阅代码
namespace ConsoleApplication2
{
class myclass
{
public unsafe void swap(int *x, int *y)
{
unsafe
{
int temp = 0;
temp = *x;
*x = *y;
*y = temp;
Console.WriteLine("Using Swap1");
Console.WriteLine("x:"+*x);
Console.WriteLine("y:" + *y);
}
}
}
class Program
{
static void Main(string[] args)
{
unsafe
{
int x = 10;
int y = 20;
int* t1 = &x;
int* t2 = &y;
myclass m1 = new myclass();
m1.swap(t1,t2);
Console.WriteLine("Main");
Console.WriteLine("x: " + x);
Console.WriteLine("y: " + y);
Console.ReadLine();
}
}
}
}
答案 6 :(得分:0)
这里我将对象作为参数传递
class person1
{
public int x, y;
public person1(int x,int y)
{
this.x = x;
this.y = y;
}
public void changes(person1 p1)
{
// int t;
this.x = x + y; //x=30 x=10,y=20
this.y = x - y; //y=30-20=10
this.x = x - y; //x=30-10=20
}
}
static void Main(string[] args)
{
person1 p1 = new person1(10,20);
p1.changes(p1);
Console.WriteLine("swapp hoge kya ?x={0} and y={1}", p1.x, p1.y);
Console.ReadKey();
}
答案 7 :(得分:0)
使用元组
int a = 4, b = 8;
(a, b) = (b, a);