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

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

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

Приветствую, ценителей красоты кода. Вот код: 2 класса «A» и «AUnit», один из которых содержит список экземпляров другого. В AUnit есть поле Name. Нужно иметь возможность менять значение этого поля, но только в том случае, если предлагаемое новое значение не используется в других экземплярах класса AUnit, которые содержаться в том же листе экземпляра класса A.
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;
            }
        }
    }
Проблема в том, что в классе AUnit нет информации о том, что содержится в классе A, поэтому так просто в него функцию типа Rename(string name) или Set для поля не сделаешь. Если же добавить метод в класс А, типа
 Public Boolean Rename(int index){…}
для смены поля в конкретном элементе списка, то тогда придется делать это поле так или иначе публичным (или через set что тоже самое) в классе AUnit, но тогда у нас это поле станет доступно для изменения без всякой проверки откуда угодно. Можно конечно сделать в классе AUnit функцию, в которой одним из параметров будет массив недопустимых имён, но это какnj некрасиво.
public Boolean Rename(String newName, String[] invalidNames){...}
Собственно абстрагируясь от языка, решением подобной проблемы был бы модификатор доступа к полю, который бы разрешал изменять поле только тому, кто содержит в себе экземпляр класса. Но тут тоже проблема – класс A содержит лист, который содержит в себе экземпляр, и кого из них считать хозяином – вопрос. Ещё как вариант в конструктор AUnit передать указатель на экземпляр класса A, тем самым получив доступ ко всему списку. И в Set поля добавить проверку. Вариант конечно, но может есть какие-то ещё уже устоявшиеся способы решения проблемы? Задача то вроде не самая редкая. Жду с интересом предложений.

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

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 };
        }
    }
}

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


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

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

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