Ограниченный доступ к изменению значения полей класса - C#

Узнай цену своей работы

Формулировка задачи:

Приветствую, ценителей красоты кода. Вот код: 2 класса «A» и «AUnit», один из которых содержит список экземпляров другого. В AUnit есть поле Name. Нужно иметь возможность менять значение этого поля, но только в том случае, если предлагаемое новое значение не используется в других экземплярах класса AUnit, которые содержаться в том же листе экземпляра класса A.
Листинг программы
  1. class Program
  2. {
  3. static void Main(string[] args)
  4. {
  5. A a = new A();
  6. // И вот тут хотелось бы сменить имя а[0] но только если новое имя, не будет равно не одном из имён а[n].
  7. Console.ReadKey();
  8. }
  9. }
  10. class A
  11. {
  12. private List<AUnit> AUnits;
  13. public AUnit this[int index]
  14. {
  15. get
  16. {
  17. return AUnits[index];
  18. }
  19. }
  20. public A()
  21. {
  22. AUnits = new List<AUnit>() { new AUnit(), new AUnit(), new AUnit() };
  23. }
  24. }
  25. class AUnit
  26. {
  27. private string NamePr;
  28. public AUnit()
  29. {
  30. NamePr = "Default";
  31. }
  32. public string Name
  33. {
  34. get
  35. {
  36. return NamePr;
  37. }
  38. }
  39. }
Проблема в том, что в классе AUnit нет информации о том, что содержится в классе A, поэтому так просто в него функцию типа Rename(string name) или Set для поля не сделаешь. Если же добавить метод в класс А, типа
Листинг программы
  1. Public Boolean Rename(int index){…}
для смены поля в конкретном элементе списка, то тогда придется делать это поле так или иначе публичным (или через set что тоже самое) в классе AUnit, но тогда у нас это поле станет доступно для изменения без всякой проверки откуда угодно. Можно конечно сделать в классе AUnit функцию, в которой одним из параметров будет массив недопустимых имён, но это какnj некрасиво.
Листинг программы
  1. public Boolean Rename(String newName, String[] invalidNames){...}
Собственно абстрагируясь от языка, решением подобной проблемы был бы модификатор доступа к полю, который бы разрешал изменять поле только тому, кто содержит в себе экземпляр класса. Но тут тоже проблема – класс A содержит лист, который содержит в себе экземпляр, и кого из них считать хозяином – вопрос. Ещё как вариант в конструктор AUnit передать указатель на экземпляр класса A, тем самым получив доступ ко всему списку. И в Set поля добавить проверку. Вариант конечно, но может есть какие-то ещё уже устоявшиеся способы решения проблемы? Задача то вроде не самая редкая. Жду с интересом предложений.

Решение задачи: «Ограниченный доступ к изменению значения полей класса»

textual
Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. namespace ConsoleApplication22 {
  7.     class Program {
  8.         static void Main(string[] args) {
  9.             A a = new A();
  10.             a.AddUnit(new AUnit { Name = "aaa" });
  11.             a.AddUnit(new AUnit { Name = "bbb" });
  12.             a.Rename("ccc", a[0]);
  13.             a[0].Name = "sss";
  14.  
  15.             Console.WriteLine(a[0].Name);
  16.             Console.WriteLine(a[1].Name);
  17.             Console.ReadLine();
  18.         }
  19.     }
  20.     public class A {
  21.         Dictionary<string, AUnit> units = new Dictionary<string, AUnit>();
  22.         public AUnit this[int index] {
  23.             get {
  24.                 return (AUnit)units.Values.ToArray()[index].Clone();
  25.             }
  26.         }
  27.         public void AddUnit(AUnit u) {
  28.             units.Add(u.Name, u);
  29.         }
  30.         public void Rename(string name, AUnit u) {
  31.             if (units.ContainsKey(name)) {
  32.                 throw new ArgumentException("name");
  33.             }
  34.             if (!units.ContainsValue(u)) {
  35.                 throw new ArgumentException("u");
  36.             }
  37.             units.Remove(u.Name);
  38.             u.Name = name;
  39.             units.Add(name, u);
  40.         }
  41.     }
  42.     public class AUnit : ICloneable {
  43.         public string Name { get; set; }
  44.         public override int GetHashCode() {
  45.             return this.ToString().GetHashCode();
  46.         }
  47.         public override bool Equals(object obj) {
  48.             return this.ToString() == obj.ToString();
  49.         }
  50.         public override string ToString() {
  51.             return string.Format("Name: {0}", Name);
  52.         }
  53.  
  54.         public object Clone() {
  55.             return new AUnit { Name = this.Name };
  56.         }
  57.     }
  58. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

10   голосов , оценка 4.3 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут