Модераторы: Partizan, gambit

Поиск:

Закрытая темаСоздание новой темы Создание опроса
> константные функции в C# 
:(
    Опции темы
Alek86
Дата 3.10.2007, 16:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 1
Всего: 25



есть ли возможность в C# объявить аналог константной функции C++?
чтобы, вызывая ее, я был уверен, что она не поменяет переменные-члены своего класса


--------------------
user posted image    user posted image
PM MAIL   Вверх
mr.DUDA
Дата 3.10.2007, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 8
Всего: 232



ИМХО, нет такого.


--------------------
user posted image
PM MAIL WWW   Вверх
iad
Дата 4.10.2007, 08:48 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 10.9.2007
Где: Москов

Репутация: 0
Всего: -2



Только так:
Код

    public class ConstantClass//класс методы которого не могут менять содержимое объекта
    {
        protected string _field;
        
        public string GetField()//const method
        {
            return _field;
        }

    }

    public class CanModifiedClass:ConstantClass//класс методы которого изменить содержимое могут
    {
        public void SetField(string f)
        {
            _field = f;
        }
    }

    public class Container
    {
        CanModifiedClass _cls = new CanModifiedClass();
        
        public ConstantClass cls//константная ссылка аля C++
        {
            get
            {
                return (ConstantClass)_cls;
            }
        }

        protected void ChangeCls()
        {
            _cls.SetField("lalala");
        }
    }

еще можно использовать модификаторы доступа internal, но это уже будет нарушением инкапсуляции
PM MAIL   Вверх
tol05
Дата 4.10.2007, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 36
Всего: 170



iad, это отдаленно напоминает реализацию свойств...

Alek86, ИМХО имеет в виду обычные плюсовые константные ф-ции. 
Если сделать свойства только на чтение и работать только через них (а это правильно, в принципе), то значения членов класса изменить будет нельзя.

Опять же, Alek86, смотря что понимать под изменением члена класса (и какой тип члена класса). Если
Код

class A
{
   private int m_i=5;

   public int GetIncrementedI()
  {
      return InternalIncrement(m_i);
  } 

   private int InternalIncrement(int value)
  {
      return ++value;
  } 
}

то m_i не изменится. Но если член класса - ссылочный, то он изменится.
Методы класса имеют неограниченный доступ к членам своего класса. Повторяю - не работай с полями класса напрямую нигде, кроме как в конструкторах, инициализаторах и свойствах.

Это сообщение отредактировал(а) tol05 - 4.10.2007, 10:35


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
VisualProgrammerNET
Дата 4.10.2007, 11:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Почётный халявщик
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.10.2005
Где: Зеленоград

Репутация: 1
Всего: 6



Цитата(iad @  4.10.2007,  08:48 Найти цитируемый пост)
еще можно использовать модификаторы доступа internal, но это уже будет нарушением инкапсуляции 

Немного я конечно не в тему... Ну почему? Почему internal - нарушение инкапсуляции? Извне сборки интернал-поля же не видны, правильно? Дык в чём проблема? Тем более порой бывает гораздо проще тупо объявить переменную интерналом, чем перелопачивать всю иерархию классов...

Да и вообще, с рефлектором не то, что internal, private поля - как на ладони...  smile 


--------------------
3 ГОДА НА user posted image 
PM MAIL ICQ   Вверх
Alek86
Дата 4.10.2007, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 1
Всего: 25



спасибо за ответы, но самый хороший ответ прозвучал у mr.DUDA smile

потому что во всех остальных примерах  я, если использую чужой класс, не могу быть уверен, что он после выполнения определенной функции не изменится.

слово const в сях давало хоть какую-то гарантию... 

и, не подскажет ли кто, почему эту возможность в шарпе убрали?


--------------------
user posted image    user posted image
PM MAIL   Вверх
iad
Дата 4.10.2007, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 10.9.2007
Где: Москов

Репутация: 0
Всего: -2



Цитата(tol05 @  4.10.2007,  11:35 Найти цитируемый пост)
Alek86, ИМХО имеет в виду обычные плюсовые константные ф-ции
 я тоже их имею ввиду

Цитата(tol05 @  4.10.2007,  11:35 Найти цитируемый пост)
Если сделать свойства только на чтение и работать только через них (а это правильно, в принципе), то значения членов класса изменить будет нельзя.
Неужели?
Код

    class a
    {
        int[] _member;
        public a()
        {
            _member = new int[2];
            _member[0] = 0;
            _member[1] = 1;
        }
        public int[] Member
        {
            get
            {
                return _member;
            }
        }
    }
    class tester
    {
        a a = new a();
        void test()
        {
            a.Member[0] = 100;
        }
    
}




PM MAIL   Вверх
tol05
Дата 4.10.2007, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 36
Всего: 170



iad

В том контексте, в котором я говорил (и с тем примером, что я привел) - я не сказал направды
Описывать все варианты, все типы данных (а потом и отличия между ними и т.д. и т.п. ) ....

Мне что, переписать себе в пост несколько толстых учебников???

Короче... даже отвечать тебе - "не сто'ит" ....

:(((


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
iad
Дата 4.10.2007, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 10.9.2007
Где: Москов

Репутация: 0
Всего: -2



Цитата(tol05 @  4.10.2007,  16:34 Найти цитируемый пост)
я не сказал направды
ты сказал правду, ты подписался в некомпетентности и поэтому ты абсолютно прав: "отвечать мне не стоит"

PM MAIL   Вверх
ivashkanet
Дата 4.10.2007, 18:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 3
Всего: 149



iad, пожалуйста без наездов! Тут идёт обсуждение! А не мерянье пип.

Тем более, что tol05, ИМХО, прав: хочешь запретить изменение элементов класса --- убери все сеттеры. 
Твой пример ни на что не годиться, так как программер, кот запретит изменение члена класса позаботиться, чтобы и этот член не имел интерфейса для прямого своего изменения.

А создавать такие классы как у тебя, а потом говорить, что я запретил изменять их элементы как минимум смешно.


PM MAIL WWW ICQ   Вверх
iad
Дата 4.10.2007, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 10.9.2007
Где: Москов

Репутация: 0
Всего: -2



Цитата(ivashkanet @  4.10.2007,  19:39 Найти цитируемый пост)
Твой пример ни на что не годиться, так как программер, кот запретит изменение члена класса позаботиться, чтобы и этот член не имел интерфейса для прямого своего изменения.
так вот программер позаботится по аналогии с моим первым примером(жаль, что невнимательно чиаешь данное обсуждение)а в С++ есть возможность без гимора решить задачу.. C# таких возможностей не дает - поэтому пытаемся скандалить smile . Если где-то я не прав - поставьте на путь истинный smile 

PM MAIL   Вверх
ivashkanet
Дата 4.10.2007, 19:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 3
Всего: 149



iad, у тя пример, всего лишь пример (хотя я такого бы не писал)... Я же описал общий подход.

Кста, для САБЖА может применяться паттерн декоратор. 
Посмотреть на его реализацию можно в самом фрэймворке. 
Класс ArrayList и статический метод ReadOnly:

Код

public static ArrayList ReadOnly(ArrayList list)
{
    if (list == null)
    {
        throw new ArgumentNullException("list");
    }
    return new ReadOnlyArrayList(list);
}


Вот сам Класс декоратор:
Код

[Serializable]
private class ReadOnlyArrayList : ArrayList
{
    // Fields
    private ArrayList _list;

    // Methods
    internal ReadOnlyArrayList(ArrayList l)
    {
        this._list = l;
    }

    public override int Add(object obj)
    {
        throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
    }

    public override void AddRange(ICollection c)
    {
        throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
    }

    public override int BinarySearch(int index, int count, object value, IComparer comparer)
    {
        return this._list.BinarySearch(index, count, value, comparer);
    }

    public override void Clear()
    {
        throw new NotSupportedException(Environment.GetResourceString("NotSupported_ReadOnlyCollection"));
    }

    public override object Clone()
    {
        ArrayList.ReadOnlyArrayList list = new ArrayList.ReadOnlyArrayList(this._list);
        list._list = (ArrayList) this._list.Clone();
        return list;
    }

    public override bool Contains(object obj)
    {
        return this._list.Contains(obj);
    }

    public override void CopyTo(Array array, int index)
    {
        this._list.CopyTo(array, index);
    }


 // .... и так далее



PM MAIL WWW ICQ   Вверх
iad
Дата 4.10.2007, 19:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 10.9.2007
Где: Москов

Репутация: 0
Всего: -2



Декоратор тоже вариант. ок.  Но проверка изменения объекта будет в рантайме. си++ый вариант позволяет отследить попытки изменения на этапе компиляции.. считаю это большим плюсом и с удовольствием бы пользовался такой возможностью smile 
PM MAIL   Вверх
tol05
Дата 5.10.2007, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1632
Регистрация: 21.12.2006
Где: Харьков

Репутация: 36
Всего: 170



Цитата(iad @  4.10.2007,  17:52 Найти цитируемый пост)
ты сказал правду, ты подписался в некомпетентности и поэтому ты абсолютно прав: "отвечать мне не стоит"


два момента:
1. Где я был некомпетентен? В какой строчке какого поста? Я не начал объяснять что есть ссылочные типы, есть типы значений и т.д. и т.п.? Не просили
2. Какова вообще была твоя цель, когда ты свой первый пост писал? Автору помочь или себя показать? Автору ты не помог и даже не пытался. Ну а себя... да, показал.

-1


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
ivashkanet
Дата 5.10.2007, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 3
Всего: 149



Цитата(iad @  4.10.2007,  19:08 Найти цитируемый пост)
си++ый вариант позволяет отследить попытки изменения на этапе компиляции.. считаю это большим плюсом и с удовольствием бы пользовался такой возможностью

Кто нить мне может объяснить нафик этот const нужен?

Я понимаю еще такую конструкцию:
Код
doSomething(const value);


Но какой толк от конструкции:
Код
void doSomething(const int value) {/*...*/}

Ведь ты САМ пишешь эту функцию и ты САМ знаешь что можно менять, а что нет. 
Зачем ещё просить компилятор: "Вот это вот менять ни в коем случае нельзя! Так что напомни, мне глупому, если я захочу это поменять..."
PM MAIL WWW ICQ   Вверх
iad
Дата 5.10.2007, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 10.9.2007
Где: Москов

Репутация: 0
Всего: -2



Цитата(ivashkanet @  5.10.2007,  11:35 Найти цитируемый пост)
Но какой толк от конструкции:код C#1:void doSomething(const int value) {/*...*/}
конечно нет толку, тем более для int. смысл есть в конструкции
Код

 public string ConstantFunction()const// - указание компилятору что эта функция не меняет состояние объекта
        {}
только она нереальна в C#. Смысл в том что я не хочу, при определенных условиях, давать возможность пользователям моего класса изменять содержимое объекта. 
Цитата(ivashkanet @  5.10.2007,  11:35 Найти цитируемый пост)
Ведь ты САМ пишешь эту функцию....Так что напомни, мне глупому, если я захочу это поменять...
Не тебе. А пользователю твоего класса, потому что не всегда проекты пишутся в одно лицо. 

PM MAIL   Вверх
ivashkanet
Дата 5.10.2007, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 3
Всего: 149



Цитата(iad @  5.10.2007,  11:20 Найти цитируемый пост)
 public string ConstantFunction()const// - указание компилятору что эта функция не меняет состояние объекта

Подробнее, плиз. Т.е. я должен помечать все функции, кот не меняют значения переменных таким образом?

И что-то я не нашел такого здесь: http://en.wikipedia.org/wiki/Const_correctness

P.S. 
Цитата(iad @  5.10.2007,  11:20 Найти цитируемый пост)
тем более для int

int это был пример. не надо быть таким категоричным

Добавлено через 1 минуту и 14 секунд
Цитата(ivashkanet @  5.10.2007,  11:33 Найти цитируемый пост)
Т.е. я должен помечать все функции, кот не меняют значения переменных таким образом?

А если не пометил, то что? Ее нельзя использовать? Требую пояснений.
(Прошу отнестись с пониманием. Я в плюсах не силен. И с такой фичей не сталкивался).
PM MAIL WWW ICQ   Вверх
iad
Дата 5.10.2007, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 10.9.2007
Где: Москов

Репутация: 0
Всего: -2



Цитата(ivashkanet @  5.10.2007,  12:33 Найти цитируемый пост)
Подробнее, плиз. Т.е. я должен помечать все функции, кот не меняют значения переменных таким образом?
ну да, типа того. Только не должен помечать, а можешь - если хочешь. это синтаксис C++, помеченная таким образом функция говорит компилятору что содержимое объекта не будет изменено. Допустим у тебя есть класс контейнер. В нем находится мембер типа Закголовок. Пусть это будет какая-нибудь коллекция, описывающая заголовок таблицы.  Причем эта коллекция - самодостаточный класс, который может использоваться для других целей, абсолютно самостоятельно. Поэтому мы не хотим его специально переписывать для класса контейнера. Есть еще в классе контейнере сама таблица в виде какого-нибудь двумерного массива. Логичиски этот массив и заголовок связаны друг с другом. Одна из размернстей таблицы и размерность заголовка должну быть одинаковы. Если по С#-пному я открою доступ (пусть даже через ридонли свойство) к заголовку, пользователь моего класса сможет сделать заголовку какой-нибудь Clear() или Resize() и размерности перестану совпадать, и пойдут рантайм ошибки. Конечно это будут ошибки проектировщика, надо было предусмотреть такую фигню, но.. Если мы предоставим доступ к заголовку как константную ссылку, то компилятор не даст дергать эту ссылку за методы Clear() или Resize(), мы же их не пометили как const... и другой разработчик, который использует твой контейнер, не сможет навредить ему при всем желании, даже не удосужившись прочитать описание. Экономия времени по любому, тк не надо изыскивать красивые архитектурные решения, для обеспечения 100%-й инкапсуляции или заморачиваться на документацию, при отказе от полной реализации этой самой инкапсуляции... Ну как мог рассказал smile

Добавлено через 9 минут и 3 секунды
в догонку
тогда появится смысл в конструкции 
Код

        void doSomething(const int value) {/*...*/}
 только опять же не int, а на основе вышесказанного что-то типа
Код

void doSomething(const container value_) {value_.Header.Clear();//error}


PM MAIL   Вверх
mr.DUDA
Дата 5.10.2007, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 8
Всего: 232



Кстати, если уж лезть в дебри, то гарантировать сохранность объектов в многопоточном приложении никто не может -- я вот не буду ничего менять, а другой поток возьмёт и изменит.


--------------------
user posted image
PM MAIL WWW   Вверх
ivashkanet
Дата 5.10.2007, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 3
Всего: 149



Цитата(iad @  5.10.2007,  17:12 Найти цитируемый пост)
не надо изыскивать красивые архитектурные решения, для обеспечения 100%-й инкапсуляции или заморачиваться на документацию, при отказе от полной реализации этой самой инкапсуляции..

Зато Вася Ламеров может спокойно удалить этот const (зачем он нужен, если компилятор на него раугается, а без него все ОК ;-)), компилятор все съест и поехало...
Цитата(iad @  5.10.2007,  17:12 Найти цитируемый пост)
Ну как мог рассказал

Нормально. Т.е. как я и думал.
PM MAIL WWW ICQ   Вверх
iad
Дата 5.10.2007, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 10.9.2007
Где: Москов

Репутация: 0
Всего: -2



Цитата(mr.DUDA @  5.10.2007,  18:32 Найти цитируемый пост)
 а другой поток возьмёт и изменит.
 ну если в моем классе, мною созданный поток - я разработчик, то да.. я и дурак. А если другой товырисч извне - то фиг ему.. не выйдет. Разумеется все касаемо данной темы.
Цитата(ivashkanet @  5.10.2007,  18:55 Найти цитируемый пост)
Зато Вася Ламеров может спокойно удалить этот const (зачем он нужен, если компилятор на него раугается, а без него все ОК ;-))
 а може забаится менят smile

PM MAIL   Вверх
mr.DUDA
Дата 5.10.2007, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 8
Всего: 232




M
mr.DUDA
Тема раскрыта полностью. Засим, во избежание дальнейших спекуляций, прикрываю её.



--------------------
user posted image
PM MAIL WWW   Вверх
Страницы: (2) [Все] 1 2 
Закрытая темаСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1169 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.