简体   繁体   English

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

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

In my case , I have bunch of values of same type , let's say floats :就我而言,我有一堆相同类型的值,比如说floats

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

Now I need a pointer or a reference value can get a instance of this floats and do operations on it.现在我需要一个指针或一个参考值可以得到这个浮点数的一个实例并对其进行操作。

in C++ :在 C++ 中:

    float* float_reference;

Now I want to set float_reference to value1 So in my functions every computation put result in value1.现在我想将 float_reference 设置为value1所以在我的函数中,每个计算都将结果放在 value1 中。

Notes : - I don't want to use classes - I don't want to use ref keyword in a functions - I don't want to use unsafe keyword注意: - 我不想使用类 - 我不想在函数中使用 ref 关键字 - 我不想使用 unsafe 关键字

I just need to do it as I said like C++ , Is there any other way around ?我只需要像 C++ 所说的那样做,还有其他方法吗?

EDIT 1 : This is why I can't use unsafe , Here's Example :编辑 1:这就是为什么我不能使用 unsafe ,这是示例:

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 : 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>

I don't want to use classes - I don't want to use ref keyword in a functions - I don't want to use unsafe keyword我不想使用类 - 我不想在函数中使用 ref 关键字 - 我不想使用 unsafe 关键字

Nope;不; those are the three options for conveying state in a reference-like way:这些是以类似参考的方式传达状态的三个选项:

  1. unmanaged pointers ( unsafe )非托管指针( unsafe
  2. managed pointers ( ref )托管指针( ref
  3. indirectly as fields on a reference-type ( class )间接作为引用类型( class )上的字段

You could also use indirection via an float[] array, Span<float> , or Memory<float> , but then you also need to convey the index;你也可以通过使用间接float[]阵列中, Span<float> ,或Memory<float> ,但你还需要传达的索引; frankly, those are all just indirect ways of getting a managed pointer to a value, so they're really just special cases of "2".坦率地说,这些都只是获取指向值的托管指针的间接方法,因此它们实际上只是“2”的特例。

The key usage in the question is this:问题中的关键用法是:

        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;
            };

        }

In that code, you are always updating value3 .在该代码中,您总是在更新value3 If we assume that this code is illustrative and that you intended to update indirectly via value_ref ;如果我们假设此代码是说明性的,并且您打算通过value_ref间接更新; we can't keep a ref float as a field (even inside a ref struct ), so fundamentally, I think the best way to reconsider this is via an array, ie我们不能将ref float作为一个字段(即使在ref struct内部),所以从根本上说,我认为重新考虑这一点的最佳方法是通过数组,即

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

Now we can use:现在我们可以使用:

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

Not quite the same as the C++, but: very effective and simple.与 C++ 不太一样,但是:非常有效和简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM