在C#中处理C++指针而不使用unsafe的最佳方法

Best way to approach C++ pointers in C# without using unsafe

本文关键字:unsafe 方法 最佳 处理 C++ 指针      更新时间:2023-10-16

在我的例子中,我有一堆相同类型的值,比如floats:

float value1 = 1.2f;
float value2 = 1.5f;
float value3 = 2.3f;

现在我需要一个指针或一个引用值来获取这个浮点的实例并对其进行操作

在C++中:

float* float_reference;

现在我想将float_reference设置为value1所以在我的函数中,每一次计算都将结果置为value1。

注意:-我不想使用类-我不想在函数中使用ref关键字-我不想使用不安全的关键字

我只需要像C++那样做,还有其他方法吗?

第1版:这就是我不能使用不安全的原因,下面是示例:

using System.Windows;

namespace ValueUpdater
{
public unsafe partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
//// need to assign one of floats to reference object
}
float value1 = 1.2f;
float value2 = 1.5f;
float value3 = 2.3f;
float* value_ref; ////// Can't Make this pointer!
private void Button_Click(object sender, RoutedEventArgs e)
{
/// Need to change the reference here
fixed (float* value_ref = &value3) {
*value_ref += 2;
};
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
/// Need to change the reference here
/// But can't use value_ref = &value3 without re-initalize
fixed (float* value_ref = &value3)
{
*value_ref -= 2;
};
}
private void Button_Click_2(object sender, RoutedEventArgs e)
{
Output.Content = value3.ToString();
}
}
}

XAML:

<Window x:Class="ValueUpdater.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ValueUpdater"
mc:Ignorable="d"
Title="MainWindow" Height="354.017" Width="368.698">
<Grid>
<Button Content="Add 2" Margin="0,28,27,0" VerticalAlignment="Top" HorizontalAlignment="Right" Width="75" Click="Button_Click"/>
<Button Content="Sub 2" Margin="0,55,27,0" VerticalAlignment="Top" HorizontalAlignment="Right" Width="75" Click="Button_Click_1"/>
<Button Content="Reset" Margin="0,83,27,0" VerticalAlignment="Top" HorizontalAlignment="Right" Width="75"/>
<Button Content="Print" Margin="0,0,27,20" HorizontalAlignment="Right" Width="75" Height="20" VerticalAlignment="Bottom" Click="Button_Click_2"/>
<Label x:Name="Output" Content="Output" HorizontalAlignment="Left" Margin="19,22,0,0" VerticalAlignment="Top" Width="182"/>
</Grid>
</Window>

我不想使用类-我不想在函数中使用ref关键字-我不希望使用不安全的关键字

没有;这是以类似参考的方式传达状态的三个选项:

  1. 非托管指针(unsafe(
  2. 托管指针(ref(
  3. 间接作为引用类型(class(上的字段

也可以通过float[]数组、Span<float>Memory<float>使用间接寻址,但也需要传递索引;坦率地说,这些都只是间接获得一个值的托管指针的方法,所以它们实际上只是"2"的特殊情况。

问题中的关键用法是:

float value1 = 1.2f;
float value2 = 1.5f;
float value3 = 2.3f;
float* value_ref; ////// Can't Make this pointer!
private void Button_Click(object sender, RoutedEventArgs e)
{
fixed (float* value_ref = &value3) {
*value_ref += 2;
};
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
fixed (float* value_ref = &value3)
{
*value_ref -= 2;
};
}

在该代码中,您总是更新value3。如果我们假设此代码是说明性的,并且您打算通过value_ref间接更新;我们不能将ref float作为一个字段(即使在ref struct内部(,所以从根本上讲,我认为重新考虑这一点的最佳方法是通过数组,即

float[] values = new [] {1.2f, 1.5f, 2.3f};
int value_index;

现在我们可以使用:

values[value_index] += 2;
...
values[value_index] -= 2;

与C++不太一样,但是:非常有效和简单。