void Afunction(int* outvar)
{
if(outvar)
*outvar = 1337;
}
Run Code Online (Sandbox Code Playgroud)
注意质量:它允许您通过引用可选地传递变量,以便可以通过函数设置它.
我最接近的猜测是(ref int?outvar)
但是那会产生ref(int?)NOT(ref int)?这就是我需要的
这个功能几乎不是c或c ++的一个特色,所以我假设必须有一些等价物?编辑:所以让我尝试一个很好的例子,我认为一个Colision检查函数是一个主要的例子,你有一个主要的测试是两个对象是否接触,然后投影矢量的可选输出,计算投影矢量需要额外的时间,所以你只想要它,如果他们想要它,另一方面,它通常使用很多在进行碰撞测试时计算的信息.
bool Collide(colObject obj1, colObject obj2, Vector3* projection)
{
//do a bunch of expensive operations to determine if there is collision
if(!collided)return false;
if(projection != NULL)
{
//do more expensive operations, that make use of the above operations already done,
//to determine the proj vect
*proj = result;
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
请注意,我目前只是将c ++代码移植到c#,所以我可能没有任何真正的"开箱即用"解决方案
你能用C#获得的最好成绩是Action<int>这样的:
void MyFunction(Action<int> valueReceiver) {
if (valueReceiver != null)
valueReceiver(1337);
}
Run Code Online (Sandbox Code Playgroud)
用法:
MyFunction(null);
MyFunction(v => someVariable = v);
Run Code Online (Sandbox Code Playgroud)
这取决于你想在C++中使用该指针的内容.您可以使用指针进行以下四项操作:
如果要执行第一个,请将其设为"out"参数.
如果要执行前两个,请将其设为"ref"参数.
如果你想做前三个,那么我通常在这种不幸的情况下做的是:
sealed class Ref<T>
{
private Action<T> setter;
private Func<T> getter;
public Ref(Action<T> setter, Func<T> getter)
{
this.setter = setter;
this.getter = getter;
}
public T Value { get { return getter(); } set { setter(value); } }
}
Run Code Online (Sandbox Code Playgroud)
现在你可以说
void M(Ref<int> r)
{
if (r != null) // 3
{
Console.WriteLine(r.Value); // 2
r.Value = 123; // 1
}
}
...
int x = 0;
M(new Ref<int>(y=>{x=y;}, ()=>x); // pass a 'ref' to x
Run Code Online (Sandbox Code Playgroud)
然后我重构代码,以便我不会为了明确改变它而传递一些东西.
或者,关于存储变量的位置有点简单但不太灵活:
class Ref<T>
{
public T Value { get; set; }
}
... M same as before ...
Ref<int> x = new Ref<int>();
x.Value = 0;
M(x);
Run Code Online (Sandbox Code Playgroud)
通过委托方案,您可以获得更大的灵活性,因为代理人当然可以做更复杂的事情,而不仅仅是获取和设置变量.
如果你想要全部四个:使用C++,而不是C#,或者使用C#的不安全子集并坚持使用指针.在普通的C#中,没有简单的方法来比较彼此的引用.
| 归档时间: |
|
| 查看次数: |
1314 次 |
| 最近记录: |