2016-10-27 3 views
-1

У меня есть классCS0212 или как установить указатель на собственность

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

видеть в журнале 2 и 1. Да, я видел

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

, но с этим в журнале 1 и 0. Обновление: Хорошо, я попытаюсь объяснить свою задачу. В форме/окне у меня много CheckBoxes. Каждый CheckBox присваивается FieldName и TableName базы данных. Он используется для динамического создания SQL-запроса. Я использую счетчик как 'abn', чтобы подсчитать, сколько полей используется для конкретной таблицы. Например: CheckBox1 присвоить Field1 и Table1 CheckBox2 назначить Field2 и Table1 CheckBox3 назначить Field1 и Table2 Когда стоит галочка увеличение «АБН» счетчика на 1. Если счетчик> 0 добавить Table1 в мой SQL запрос и конкретной области. Когда CheckBox снят с отметки Unchecked, уменьшите на 1. Если counter = 0, я удаляю Table1 из SQL-запроса. И я решил эту задачу в Delphi с указателями. И теперь я начинаю переносить этот проект на C# и придерживаться этого. Да, я понимаю, что он требует «фиксированного», но, как я написал «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, но его Dont second time

+0

@Sinatr К сожалению, CS0212 конечно –

+0

, как я могу назвать свое имя в комментариях, его странный синтаксис – Sherlock

+0

@MidTwo, вам не нужно, он «OP» (оригинальный плакат);) – Sinatr

ответ

0

я предлагаю небольшое изменение кода в этом ответе, но я бы на самом деле советую перепроектировать большие части вашего приложения для того, чтобы он соответствует архитектуре 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()); 
} 

Надеюсь, я не добавил никаких опечаток, не могу скомпилировать свои изменения прямо сейчас.

+0

Это работает, но это не сработает для моей задачи. Я написал общественный класс Поле { общественный байт Count {get; задавать; } } как короткий пример. Полный класс выглядит так public class TArrF { public virtual bool Проверено {get; задавать; } = false; public string Поле; public string Table; public string Usl; public int Ind; // используется для создания порядка полей public unsafe byte * Yk; общественный небезопасный байт * Fil; } –

+0

и когда я установлю для [1] .Field = «Field1» и [2] .Field = «Field2» в [1] .Field также становятся «Field2», потому что это тот же объект, поэтому ваш вариант не подходит ко мне. Но тем не менее спасибо. Я все еще думаю, что указатели - это мой вариант .... –

+0

@ ИгорьРадченко Его не указатели ... его вложенные объекты. См. Мое обновление, чтобы указать свойства для поля и назначить счетчики, которые одинаковы для некоторых полей, и другие для других. Как уже было сказано, вы, вероятно, НИКОГДА НЕ требуете 'unsafe', пока вы останетесь в области C# – grek40

Смежные вопросы