Ограниченный доступ к изменению значения полей класса - 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 };
}
}
}