Ограниченный доступ к изменению значения полей класса - C#
Формулировка задачи:
Приветствую, ценителей красоты кода.
Вот код: 2 класса «A» и «AUnit», один из которых содержит список экземпляров другого. В AUnit есть поле Name. Нужно иметь возможность менять значение этого поля, но только в том случае, если предлагаемое новое значение не используется в других экземплярах класса AUnit, которые содержаться в том же листе экземпляра класса A.
Проблема в том, что в классе AUnit нет информации о том, что содержится в классе A, поэтому так просто в него функцию типа Rename(string name) или Set для поля не сделаешь.
Если же добавить метод в класс А, типа
для смены поля в конкретном элементе списка, то тогда придется делать это поле так или иначе публичным (или через set что тоже самое) в классе AUnit, но тогда у нас это поле станет доступно для изменения без всякой проверки откуда угодно.
Можно конечно сделать в классе AUnit функцию, в которой одним из параметров будет массив недопустимых имён, но это какnj некрасиво.
Собственно абстрагируясь от языка, решением подобной проблемы был бы модификатор доступа к полю, который бы разрешал изменять поле только тому, кто содержит в себе экземпляр класса. Но тут тоже проблема – класс A содержит лист, который содержит в себе экземпляр, и кого из них считать хозяином – вопрос.
Ещё как вариант в конструктор AUnit передать указатель на экземпляр класса A, тем самым получив доступ ко всему списку. И в Set поля добавить проверку. Вариант конечно, но может есть какие-то ещё уже устоявшиеся способы решения проблемы? Задача то вроде не самая редкая.
Жду с интересом предложений.
class Program { static void Main(string[] args) { A a = new A(); // И вот тут хотелось бы сменить имя а[0] но только если новое имя, не будет равно не одном из имён а[n]. Console.ReadKey(); } } class A { private List<AUnit> AUnits; public AUnit this[int index] { get { return AUnits[index]; } } public A() { AUnits = new List<AUnit>() { new AUnit(), new AUnit(), new AUnit() }; } } class AUnit { private string NamePr; public AUnit() { NamePr = "Default"; } public string Name { get { return NamePr; } } }
Public Boolean Rename(int index){…}
public Boolean Rename(String newName, String[] invalidNames){...}
Решение задачи: «Ограниченный доступ к изменению значения полей класса»
textual
Листинг программы
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication22 { class Program { static void Main(string[] args) { A a = new A(); a.AddUnit(new AUnit { Name = "aaa" }); a.AddUnit(new AUnit { Name = "bbb" }); a.Rename("ccc", a[0]); a[0].Name = "sss"; Console.WriteLine(a[0].Name); Console.WriteLine(a[1].Name); Console.ReadLine(); } } public class A { Dictionary<string, AUnit> units = new Dictionary<string, AUnit>(); public AUnit this[int index] { get { return (AUnit)units.Values.ToArray()[index].Clone(); } } public void AddUnit(AUnit u) { units.Add(u.Name, u); } public void Rename(string name, AUnit u) { if (units.ContainsKey(name)) { throw new ArgumentException("name"); } if (!units.ContainsValue(u)) { throw new ArgumentException("u"); } units.Remove(u.Name); u.Name = name; units.Add(name, u); } } public class AUnit : ICloneable { public string Name { get; set; } public override int GetHashCode() { return this.ToString().GetHashCode(); } public override bool Equals(object obj) { return this.ToString() == obj.ToString(); } public override string ToString() { return string.Format("Name: {0}", Name); } public object Clone() { return new AUnit { Name = this.Name }; } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д