2015-05-06 3 views
0

Я пытаюсь написать простую игру. Я хочу создать объект «контроллер движения», который будет обрабатывать инструкции перемещения от двигателя. Я также хотел бы, чтобы этот объект выставлял метод, который бы проверял его состояние и возвращал true/false в зависимости от того, готов ли он двигаться или нет. Состояние будет сохранено как группа булевых переменных. Поскольку их много, я решил объединить их в новую структуру под названием «флаги». Вот как это выглядит более или менее:C# accessing struct members внутри методов класса

public class movContr 
{ 
    int movId; 
    public struct flags 
    { 
     bool isMoving; 
     bool isLocked; 
     bool isReady; 
     (...) 
    } 

    public bool CheckReadiness() 
    { 
     if(flags.isReady==true) return true; 
     return false; 
    } 
} 

Теперь проблема это не будет компилироваться, ошибки являются:

error CS0120: An object reference is required to access non-static member 

обижая линии являются:

if(flags.isReady==true) return true; 

Я предположим, что C# не рассматривает структуры, подобные блогам памяти, которые просто содержат переменные в заказах, но, как и некоторые «особые» кузены класса.

Вот мои вопросы:

как я должен ручке обращающегося членов класса структуры в своих методах? Как я могу ссылаться на методы класса для членов его будущих экземпляров? Я попробовал это вместо этого:

if(this.flags.isReady==true) return true; 

но я получаю ту же ошибку.

В качестве альтернативы, если инкапсуляция переменных моего флага с помощью «struct» не является правильным способом, что это такое?

Я попытался найти ответ сам, но поскольку все ключевые слова, которые я мог придумать, очень общие, так же как и результаты. Большинство из них касаются статических членов, которые здесь не являются решением, так как мне нужны несколько независимых экземпляров класса movContr.

+0

Я не уверен, что вам даже нужна структура. Похоже, вы можете просто создавать свойства или поля в своем классе для каждого из полей в этой структуре. – juharr

+0

не могу поверить, что это было так просто, извините, я не могу принять более одного ответа :(Несколько дней я чувствую, что должен придерживаться ассемблера, которого я клянусь @juharr, так как это находится на очень ранней стадии, и моя память очень плохо, я хочу, чтобы он был максимально читабельным, если мне нужно сделать перерыв в проекте. Он не является структурой, но я хотел бы обращаться к флагам так же, как movContrObj.flags. isMoving, по крайней мере на данный момент – Searant

+0

Лично я считаю, что использование структуры здесь менее читаемо, но если вам более удобно, тогда нет никакого реального вреда. – juharr

ответ

2

Вы создали объявление структуры под названием flags. Но это только декларация, а не конкретное значение. Таким образом, фрагмент кода

if(flags.isReady==true) return true; 

пытается получить доступ к статическому члену (https://msdn.microsoft.com/en-us/library/98f28cdx.aspx).

Вы должны объявить переменную этого типа для того, чтобы использовать его:

private flags myFlag; 

public bool CheckReadiness() 
{ 
    if(myFlag.isReady==true) return true; 
     return false; 
} 

Может быть, ваша путаница происходит из C++, где «рядный, анонимный» структура допускается:

struct { 
    int some_var 
} flags; 

flags.some_var = 1; 

Недоступно в C#

+0

Я прихожу из более низкого уровня, используя такие вещи, как перегрузка оператора по-прежнему заставляет мои лодыжки иногда набухать :), который сказал, что если я когда-либо выработаю все причуды, язык, такой как C#, кажется, идеально подходит для сценариев игр и т. д. (не уверен, как это работает с точки зрения производительности) – Searant

0

Как исключение предлагает Вам нужно создать экземпляр ударил, как показано ниже: -

flags flag; 
flag.isReady = true; 

Для получения дополнительной информации: -

http://www.dotnetperls.com/struct

Пожалуйста, обратите внимание, как, в главном, то struct создается в стеке. Не используется «новое» ключевое слово. Он используется как тип значения, такой как int.

Кстати я хотел бы предложить вам использовать авто реализованы свойства вместо Поразило, если это единственное применение, как показано в коде

Ref: - https://msdn.microsoft.com/en-us/library/bb384054.aspx

0

Вы не можете использовать flags, потому что вы только объявляете тип данных с помощью «struct flags». Вам нужно создать экземпляр.

, и вы должны объявлять поля структуры как общедоступные. иначе вы не сможете получить к ним доступ.

int movId; 

    // Delace fields as public 
    public struct flags 
    { 
     public bool isMoving; 
     public bool isLocked; 
     public bool isReady; 
    } 

    // create a instance 
    private flags myFlag; 

    public bool CheckReadiness() 
    { 
     if(this.myFlag.isMoving == true) return true; 
     return false; 
    } 

    // Better Implementation 
    public bool CheckReadiness() 
    { 
     if (this.myFlag.isMoving) return true; 
     return false; 
    } 

    // Best Implementation 
    public bool CheckReadiness() 
    { 
     return (this.myFlag.isMoving); 
    } 
0

Вместо создания структуры может иметь смысл иметь свойства.

public class movContr 
{ 
    int movId; 

    public bool IsMoving { get; set; } 
    public bool IsLocked { get; set; } 
    public bool IsReady { get; set; } 
     (...) 
} 

Тогда вместо вызова CheckReadiness вы бы просто позвонить IsReady.

var temp = new movContr(); 
if(temp.IsReady) 
{ 
    // It is ready. 
} 
+0

это имеет смысл, но позже проверка готовности может стать довольно тяжелой для CPU, и мне все равно понадобится кэшированное значение somwhere, так что он не будет выполняться снова и снова. – Searant

+0

Авто свойства - это всего лишь короткая рука для методов getter и setter. поддержка поле. Не уверен, как это увеличит нагрузку на процессор над методом, который возвращает значение из структуры. В обоих случаях доступные значения находятся в стеке. – juharr

+0

Я имел в виду, что сейчас CheckReadiness() проверяет значение isReady, но, надеюсь, в ближайшем будущем он будет включать в себя и некоторые сложные вычисления. Поэтому мне лучше позвонить CheckReadiness() только тогда, когда мне действительно нужно, и его результат будет кэширован в isReady для более позднего недорогого доступа. – Searant

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