Ну, название говорит об этом, но я буду более конкретным в своей ситуации и объясню свою проблему. У меня есть следующие классы:
class Attribute{
private int score;
private int tempScore;
private int misc;
// here I have getters and setters
// A method
public int Modifier(){
return (score+tempScore-10)/2;
}
}
а также
class SavingThrow{
private int base;
private int resistance;
private int bonus;
private int misc;
//Getters and setters here
//A method
public int Total(){
return base + resistance + bonus + misc;
}
}
Скажем, теперь у меня есть игрок А с мудростью Атрибута и SavingThrow. Всякий раз, когда изменяется первый, например:
A.Wisdom.Score = 12;
то второе должно быть изменено как следствие. В этом примере я должен сделать:
A.Will.Bonus = A.Wisdom.Modifier();
Любая идея о том, как достичь этого?
Я подумал о следующем решении, но это не удовлетворяет меня по той причине, которую я собираюсь объяснить.
Я не буду определять геттеры, поэтому внешний доступ к Мудрости может быть выполнен только с помощью предопределенного публичного метода, например SetWisdom (int score), и в этом методе я обновляю Will. Хотя проблема заключается в том, что если мне нужно изменить tempScore или misc вместо этого, я должен сделать другой метод для этого. Это кажется довольно неэффективным, особенно если я добавлю дополнительные поля в класс атрибутов.
Кроме того, я мог бы использовать метод SetWisdom (атрибут мудрости), который заменяет весь атрибут новым объектом, в котором я должен скопировать ВСЕ немодифицированные поля и заменить тот, который мне нужен. Это кажется немного неуклюжим и нелепым. Какое решение вы бы выбрали и, что более важно, у вас есть лучшие идеи о том, как справиться с этим?
Самый простой вариант - не делать копии значения вообще, тогда вам не нужно отслеживать, где вы его скопировали, чтобы обновить его.
class SavingThrow{
private int base;
private int resistance;
private Attribute attribute;
private int misc;
//Getters and setters here
//A method
public int Total(){
return base + resistance + attribute.Modifier + misc;
}
}
Ваш класс может использоваться таким образом, если вы установите атрибут в конструкторе:
Attribute wisdom = new Attribute(16);
SavingThrow will = new SavingThrow(wisdom);
Console.WriteLine(will.Total());
wisdom.Add(2);
Console.WriteLine(will.Total());
Общий балл должен был увеличиться (при условии, что добавление двух к мудрости увеличивает модификатор), потому что класс спасброска никогда не содержал копию, но напрямую ссылался на мудрость.
size
а у ArmorClass есть поле size
. Тем не менее, я вынужден скопировать его сейчас, потому что это не объект, а примитив (также я не могу оставить поле только в ArmorClass, потому что он нужен мне в Player для других классов). Должен ли я использовать указатель? Хотя это unsafe
территория, поэтому я не уверен, что это правильное решение. Или я должен просто упаковать это в классе и использовать это?
base
- это ключевое слово в C #, его нельзя использовать как имя переменной.INotifyPropertyChanged
. Ваши поля должны будут поменяться на свойства, и пока вы там, вы можете также изменить свои методыTotal
иModifier
на свойства только для чтения, чтобы соответствовать стандартному использованию .NET.