CS0212或如何设置指向属性的指针

本文关键字:属性 指针 设置 何设置 CS0212 | 更新日期: 2023-09-27 18:15:04

我有class

public class ForAllViewModel
  {
    byte abn;
    byte abn2;
    public ObservableCollection<TArrF> a
    public class TArrF
      {
        public unsafe byte* Yk;
      }  
 }

当我写

a[1].Yk = &abn;
a[2].Yk = &abn2;
abn =1;
abn2 = 0;

显示错误

错误CS0212:只能在固定语句初始化式中使用非固定表达式的地址。

我想要的是

(*a[1].Yk)+=1;
(*a[2].Yk)+=1;
Console.WriteLine(abn.ToString());
Console.WriteLine(abn2.ToString());

在日志21中可见。是的,我看到了

fixed (byte* p = &abn) { a[1].Yk = p; }

,但与此log 10。更新:好的,我会试着解释我的任务。在窗体/窗口我有许多复选框。每个复选框分配给数据库的FieldName和TableName。它用于动态构建SQL查询。我使用像'abn'这样的计数器来计算特定表使用了多少字段。例如:CheckBox1分配给Field1和Table1CheckBox2分配给Field2和Table1CheckBox3分配给Field1和Table2当CheckBox被选中时,计数器'abn'增加1。如果counter> 0,我将表1添加到我的SQL查询和特定字段。当"复选框"为"未选中"时,计数器减少1。如果counter = 0,则从SQL查询中删除表1。我用指针在Delphi中解决了这个问题。现在我开始把这个项目移植到c#上,并坚持了下来。是的,我明白它需要'fixed',但正如我写的'fixed (byte* p = &abn) {a[1]。Yk = p;这不能给我正确的结果。因为当我做'*a[1]。yk +=1;' 'abn'也应该变大1。但事实并非如此。这意味着我把指针设置错了。所以我搜索正确的方式。

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication5
{
/// <summary>
/// Логика взаимодействия для MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    byte abn, abn2;
    public class Field
    {
       public string Table;
       public string Field;
       public unsafe byte* Yk;
    }
    public ObservableCollection<Field> a;

    public MainWindow()
    {
        InitializeComponent();
        a = new ObservableCollection<Field>();
        abn = 0;
        abn = 0;
        a.Add(new Field());
        a.Add(new Field());
        a.Add(new Field());
        a.Add(new Field());
        a[1].Table="Table_1";
        a[1].Field="Field_1";
        a[2].Table="Table_1";
        a[2].Field="Field_2";
        a[3].Table="Table_2";
        a[3].Field="Field_1";
        unsafe
        {
            fixed (byte* p = &abn) { a[1].Yk = p; }
            fixed (byte* p = &abn) { a[2].Yk = p; }
            fixed (byte* p = &abn2) { a[3].Yk = p; }
        }
    }
    private void CheckEdit_EditValueChanged(object sender, DevExpress.Xpf.Editors.EditValueChangedEventArgs e)
    {
        unsafe
        {
            Console.WriteLine("abn BEFORE modification: "+abn.ToString());
            Console.WriteLine("abn2 BEFORE modification: " + abn2.ToString());
            DevExpress.Xpf.Editors.CheckEdit cb = sender as DevExpress.Xpf.Editors.CheckEdit;
            byte i = Convert.ToByte(cb.Tag);
            if ((bool)cb.IsChecked)
            {
                *a[i].Yk += 1;
                //if(*a[i].Yk==1) { addTabletoSQL(a[i].Table);} 
                //addFieldtoSQL(a[i].Field);
            }
            else
            {
                *a[i].Yk -= 1;
                //if(*a[i].Yk==0) { removeTablefromSQL(a[i].Table);} 
                //removeFieldfromSQL(a[i].Field);
            }
            Console.WriteLine("abn AFTER modification: " + abn.ToString());
            Console.WriteLine("abn2 AFTER modification: " + abn2.ToString());
        }
    }
}
}

添加一些行来更清楚我看到项目应该如何工作(以及它如何在Delphi中工作)和xaml

<Grid>
    <dxe:CheckEdit HorizontalAlignment="Left" Margin="39,28,0,0" VerticalAlignment="Top" Width="150" Content="Field 1" Tag="1" EditValueChanged="CheckEdit_EditValueChanged" />
    <dxe:CheckEdit HorizontalAlignment="Left" Margin="39,55,0,0" VerticalAlignment="Top" Width="150" Content="Field 2" Tag="2" EditValueChanged="CheckEdit_EditValueChanged"  />
    <dxe:CheckEdit HorizontalAlignment="Left" Margin="39,82,0,0" VerticalAlignment="Top" Width="150" Content="Field 3" Tag="3" EditValueChanged="CheckEdit_EditValueChanged"  />
</Grid>

所以,当我选中复选框abn=2和abn2=1时。它是正确的。但当我勾选时- abn和abn2应该是0,但它不是第二次

CS0212或如何设置指向属性的指针

在这个答案中,我建议对你的代码做一个小的改变,但是我实际上建议重新设计你的应用程序的更大的部分,以使它适合WPF架构。

而不是你的代码

byte abn, abn2;
public class Field
{
   public unsafe byte* Yk;
}
public ObservableCollection<Field> a;

你可以使用:

FieldCount abn, abn2;
public class FieldCount
{
    public byte Count { get; set; }
}
public class Field
{
    public string Name { get; set; }
    public FieldCount Yk { get; set; }
}
public ObservableCollection<Field> a;

然后相应地更改初始化:

a = new ObservableCollection<Field>();
abn = new FieldCount { Count = 0 };
// note I assume you don't want to double initialize abn
abn2 = new FieldCount { Count = 0 };
// add fields to the collection
a.Add(new Field { Name = "Field X", Yk = abn });
a.Add(new Field { Name = "Field Y", Yk = abn });
a.Add(new Field { Name = "Field Z", Yk = abn2 });
a.Add(new Field());

并更改选中的事件处理程序

private void CheckEdit_EditValueChanged(object sender, DevExpress.Xpf.Editors.EditValueChangedEventArgs e)
{
    Console.WriteLine("abn BEFORE modification: " + abn.Count.ToString());
    Console.WriteLine("abn2 BEFORE modification: " + abn2.Count.ToString());
    var cb = sender as DevExpress.Xpf.Editors.CheckEdit;
    byte i = Convert.ToByte(cb.Tag);
    if ((bool)cb.IsChecked)
    {
        a[i].Yk.Count += 1;
    }
    else
    {
        a[i].Yk.Count -= 1;
    }
    Console.WriteLine("abn AFTER modification: " + abn.Count.ToString());
    Console.WriteLine("abn2 AFTER modification: " + abn2.Count.ToString());
}

希望我没有添加任何拼写错误,现在无法编译我的更改