Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.10.2011, 21:36   #1
Lasur
Форумчанин
 
Аватар для Lasur
 
Регистрация: 13.10.2011
Сообщений: 143
По умолчанию Как "спрятать" константу

Столкнулся со следующей проблемой:
В классе есть ссылочное свойство, нужно чтобы его можно было получить, но нельзя было изменить. Модификатор readonly не позволяет задавать лишь ссылку (и то лишь напрямую), но позволяет менять ее свойства. Аналогично с аксессорами get/set. Можно ли запретить любые ее изменения без использования метода Clone?
Вот что я имею в виду:
Код:
public class MyClass
{
	public string s;
	public static readonly MyClass x = new MyClass("NOT CHANGED");
	public MyClass(string s)
	{
		this.s = s;
	}
}

public class Tests
{
	static void Main()
	{
		Console.WriteLine(MyClass.x.s);
		//MyClass.x = new MyClass("CHANGED");
		MyClass.x.s = "CHANGED";
		Console.WriteLine(MyClass.x.s);
		Console.ReadLine();
	}
}
Все имена, фамилии, ники, даты и события упоминаемые в моих постах, являются вымышленными. Все совпадения с реально существующими - случайны.
Lasur вне форума Ответить с цитированием
Старый 23.10.2011, 22:54   #2
Скарам
Дружите с Linq ;)
Форумчанин
 
Аватар для Скарам
 
Регистрация: 15.10.2008
Сообщений: 822
По умолчанию

Можно сделать set приватным, а get public.
Не давай организму поблажки, каждый день тренируй его в шашки..
Скарам вне форума Ответить с цитированием
Старый 24.10.2011, 07:19   #3
Руслантус
Наркоман самоучка
Форумчанин
 
Аватар для Руслантус
 
Регистрация: 22.07.2007
Сообщений: 276
По умолчанию

Можно ввести булеву переменную - isLock. Если она true, то выдаём исключение InvalidOperation, либо просто возвращаем default значение типа свойства.
#include <мозг.h>
Руслантус вне форума Ответить с цитированием
Старый 24.10.2011, 07:51   #4
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

В случае с простыми типами пойдёт вариант, который предложил Скарам:
Код:
public class MyClass
{
	private string s;
	public static readonly MyClass x = new MyClass("NOT CHANGED");
	public MyClass(string s)
	{
		this.s = s;
	}
           public string Str
           {
             get
             {
               return s;
             }
             private set
             {
               s = value;
             }
           }
}
Если вместо s будет объект класса, то в get можно поместить клонирование объекта и возвращать копию. Но это сомнительное решение будет с точки зрения пользовательского кода
pu4koff вне форума Ответить с цитированием
Старый 24.10.2011, 10:35   #5
Guy
Форумчанин
 
Регистрация: 15.12.2010
Сообщений: 398
По умолчанию

Зачем приватный сет ... начинаете же правильно

Код:
class MyClass : ICloneable
{
private static readonly MyClass x = new MyClass("NOT CHANGED");
public MyClass XX
{
get { return x.Clone(); }
...// Конструктор тот же
}
public object Clone()
{
// Тут руками делай дубликат твоего объекта MyClass  в переменной х
}
}
Guy вне форума Ответить с цитированием
Старый 24.10.2011, 10:54   #6
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Цитата:
Сообщение от Guy Посмотреть сообщение
Зачем приватный сет ... начинаете же правильно

Код:
class MyClass : ICloneable
{
private static readonly MyClass x = new MyClass("NOT CHANGED");
public MyClass XX
{
get { return x.Clone(); }
...// Конструктор тот же
}
public object Clone()
{
// Тут руками делай дубликат твоего объекта MyClass  в переменной х
}
}
Куда дели член s, который и должен защищаться от изменения? В данном случае и защищать нечего. А вот высовывать члены класса наружу без свойств - это уныло. При условии, что шарп умеет такую запись:
Код:
public string Str {get;set;}
pu4koff вне форума Ответить с цитированием
Старый 24.10.2011, 15:05   #7
Lasur
Форумчанин
 
Аватар для Lasur
 
Регистрация: 13.10.2011
Сообщений: 143
По умолчанию

Приведенный мною код не совсем отражает суть проблемы, так как вместо string действительно стоит ссылочный тип. Поэтому я извиняюсь и выкладываю оригинал, породивший вопрос)
Код:
public class LargeNumber : ICloneable
{
	public const int Capacity = 4; //Кол-во long-ов, необходимых для хранения числа. Оно же размерность массива - содержимого.
	public const int Length = Capacity * 4; //Кол-во байт, необходимых для хранения числа.
	ulong[] Number = new ulong[Capacity]; //Массив, хранящий содержимое числа.
	static uint[] Pow2 = new uint[32]; //Массив степеней двойки, нужен для SetBit().

	public static readonly LargeNumber Zero; //Константа 0.
	public static readonly LargeNumber One; //Константа 1.
	public static readonly LargeNumber MaxValue; //Константа, представляющая максимальное значение числа.

	static LargeNumber() //Статистический конструктор для инициализации констант, приведенных выше.
	{
		ulong[] arr = new ulong[Capacity];
		Zero = new LargeNumber { Number = (ulong[])arr.Clone() };
		arr[3] = 1L;
		One = new LargeNumber { Number = (ulong[])arr.Clone() };
		for (int i = 0; i < Capacity; i++) arr[i] = uint.MaxValue;
		MaxValue = new LargeNumber { Number = (ulong[])arr.Clone() };
		for (int i = 0; i < 32; i++) Pow2[i] = (uint)Math.Pow(2, i);
	}

	public void SetBit(int pos, bool bit)//Задает i-ый бит вызвавшего числа.(true=1, false=0).
	{
		Number[pos / 32] = bit ? Number[pos / 32] | Pow2[31 - pos % 32] : Number[pos / 32] & (~Pow2[31 - pos % 32]);
	}
	public object Clone()
	{
		return new LargeNumber { Number = (ulong[])this.Number.Clone() };
	}
}
Итак, readonly поля должны быть получаемыми, но не изменяемыми. Этому очень мешает метод SetBit, изменяющий бит числа. На текущий момент мое решение - сделать этот метод приватным.
Если написать
Код:
public static LargeNumber Zero { get { return (LargeNumber)LargeNumber.Zero.Clone();  } set { LargeNumber.Zero = value; } }
возникает StackOverflow, предположительно вызываемый в static конструкторе. Я так понимаю именно во избежание этого в посте #4 pu4koff создает вспомогательный string. Объясните тогда, пожалуйста, где происходит переполнение.
Все имена, фамилии, ники, даты и события упоминаемые в моих постах, являются вымышленными. Все совпадения с реально существующими - случайны.

Последний раз редактировалось Lasur; 24.10.2011 в 15:18.
Lasur вне форума Ответить с цитированием
Старый 24.10.2011, 15:54   #8
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Код:
get { return (LargeNumber)LargeNumber.Zero.Clone();  }
get обращается к такому же get. Назовите член класса и свойство разными именами.
pu4koff вне форума Ответить с цитированием
Старый 24.10.2011, 16:04   #9
Lasur
Форумчанин
 
Аватар для Lasur
 
Регистрация: 13.10.2011
Сообщений: 143
По умолчанию

Алгоритм решения понятен, спасибо за ответы.
Все имена, фамилии, ники, даты и события упоминаемые в моих постах, являются вымышленными. Все совпадения с реально существующими - случайны.
Lasur вне форума Ответить с цитированием
Старый 24.10.2011, 21:40   #10
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

Lasur

readonly поля должны быть получаемыми, но не изменяемыми

отдавайте в get интерфейс, у которого нет set-методов
Rififi вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как "повесить " передачу данных из формы на событие нажатия кнопки типа "button" ? vedro-compota JavaScript, Ajax 10 14.12.2010 21:05
Как обойти "преобразование типа из "string" в "float" невозможно" lexluter1988 Помощь студентам 1 07.08.2010 12:23
"ОКРВВЕРХ", "ОКР", "ЕСЛИ". Как бы их связать. Каравай Microsoft Office Excel 13 17.02.2010 09:53
при вводе на листе "магазин"- код товара появлялось "описание" товара из "склада" с "продажной ценой" aleksei78 Microsoft Office Excel 13 25.08.2009 12:04
Как сделать ссылку на "константу"? Loobtuff Microsoft Office Excel 2 21.09.2007 13:29