C# Question

CS0212 or how to set pointer to property

I have class

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


when I wrote

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


it gives me error


error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer.


All I want is after

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


to see in log
2
and
1
.
Yes, I saw

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


but with this in log
1
and
0
.
Update:
Ok, I will try to explain my task.
On form/window I have many CheckBoxes. Every CheckBox assign to FieldName and TableName of Data Base. It is used for dynamically build SQL query.
I use counter like 'abn' to count how many fields are used for specific table.
For example:
CheckBox1 assign to Field1 and Table1
CheckBox2 assign to Field2 and Table1
CheckBox3 assign to Field1 and Table2
When CheckBox is Checked counter 'abn' increase by 1. If counter > 0 I add Table1 to my SQL query and specific field. When CheckBox is Unchecked counter decrease by 1. If counter = 0 I remove Table1 from SQL query.
And I solved this task in Delphi with pointers. And now I start porting this project to C# and stuck on this.
Yes, I understand that it requires 'fixed', but as I wrote 'fixed (byte* p = &abn) { a[1].Yk = p; }' doesnt give me right result.
Because when I do '*a[1].Yk+=1;' 'abn' also should become for 1 greater. But it doesnt. It means I set pointer in wrong way. So I search right way.

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


Add some lines to more clear how I see project should work (and how it works in Delphi) and 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>


So, when I Check CheckBoxes abn=2 and abn2=1. It`a right. But when I Unchecked - abn and abn2 should become 0, but its dont
second time

Answer

I propose a small change to your code in this answer, however I'd actually advise to redesign larger parts of your application in order to make it fit with the WPF architecture.

Instead of your code

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

You could use:

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;

Then change your initialization accordingly:

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());

And change the checked event handler

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

Hope I didn't add any typos, can't compile my changes right now.