powered by simpleCommunicator - 2.0.54     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Класс AnsiString
24 сообщений из 24, страница 1 из 1
Класс AnsiString
    #38903957
Алексей Ку.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, знатоки!

Я всё-таки взялся за реализацию класса AnsiString, который будет соответствовать своему "тёзке" из С++.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
  public class AnsiString
    {
        private string value;

        public AnsiString(string _s)
        {
            value = _s;
        }
        public static implicit operator AnsiString(string address)
        {
            if (address == null)
                return null;

            return new AnsiString(address);
        }

        public static bool operator !=(AnsiString left, AnsiString right)
        {
            return left.value != right.value;
        }
        public static bool operator == (AnsiString left, AnsiString right)
        {
            return left.value == right.value;
        }
        public int IndexOfCPP(string pattern)
        {
            return value.IndexOf(pattern) + 1;
        }
        public int IndexOfCPP(char pattern, int startindex)
        {
            return value.IndexOf(pattern, startindex - 1) + 1;
        }
        public int IndexOfCPP(char pattern)
        {
            return value.IndexOf(pattern) + 1;
        }

        public string RemoveCPP(int startindex, int lenght)
        {
            return value.Remove(startindex - 1, lenght);
        }

        public string SubstringCPP(int startindex, int lenght)
        {
            return value.Substring(startindex - 1, lenght);
        }

        public static string StringReplace(string S, string OldPattern, string NewPattern)
        {
            return S.Replace(OldPattern, NewPattern);
        }

        public static string StringReplace(string S, char OldPattern, char NewPattern)
        {
            return S.Replace(OldPattern, NewPattern);
        }
        public string SetLenght(int lenght)
        {
            return value.Substring(0, lenght);
        }

        public bool IsEmpty()
        {
            return string.IsNullOrEmpty(value);
        }
    }



Теперь я могу проводить основные операции со строкой, которые мне нужны.
Я могу инициализировать класс след. образом:
Код: c#
1.
            AnsiString a = "asd";



Вопрос: как мне сделать неявную конвертацию к строке. Т.е. я хочу выполнять след операции:
Код: c#
1.
2.
3.
AnsiString a = "asd";

string s = a;//Неявно надо конвертировать в строку


Ещё одна задача: Сделать, чтобы в Debug режиме, при наведении на переменную типа AnsiString, мне показывалось сразу его value. Ну т.е. как и у класса String.
...
Рейтинг: 0 / 0
Класс AnsiString
    #38903985
Фотография Axeleron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Ку.Вопрос: как мне сделать неявную конвертацию к строке. Т.е. я хочу выполнять след операции:
Код: c#
1.
2.
3.
AnsiString a = "asd";

string s = a;//Неявно надо конвертировать в строку



Написать extension method в AnsiString классе.

Алексей Ку.Ещё одна задача: Сделать, чтобы в Debug режиме, при наведении на переменную типа AnsiString, мне показывалось сразу его value. Ну т.е. как и у класса String.
Добавить соответствующий property в AnsiString классе.
...
Рейтинг: 0 / 0
Класс AnsiString
    #38904022
Ilya81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Ку.Вопрос: как мне сделать неявную конвертацию к строке.
Аналогично. Оператор должен содержать лишь хотя б одно использование класса, в котором он объявлен, не важно какое.
Код: c#
1.
public static implicit operator string(AnsiString address)


Алексей Ку.делать, чтобы в Debug режиме, при наведении на переменную типа AnsiString, мне показывалось сразу его value. Ну т.е. как и у класса String.
Переопределить метод ToString.
...
Рейтинг: 0 / 0
Класс AnsiString
    #38904042
Алексей Ку.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AxeleronАлексей Ку.Вопрос: как мне сделать неявную конвертацию к строке. Т.е. я хочу выполнять след операции:
Код: c#
1.
2.
3.
AnsiString a = "asd";

string s = a;//Неявно надо конвертировать в строку



Написать extension method в AnsiString классе.

Алексей Ку.Ещё одна задача: Сделать, чтобы в Debug режиме, при наведении на переменную типа AnsiString, мне показывалось сразу его value. Ну т.е. как и у класса String.
Добавить соответствующий property в AnsiString классе.

Со вторым вопросом всё ясно -тупанул.

При попытке добавить extension
public static string ToString(this AnsiString input)
{
//convert
}

получаю:
Extension method must be defined in a non-generic static class

Как быть?
...
Рейтинг: 0 / 0
Класс AnsiString
    #38904059
Алексей Ку.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разобрался!

Вот получается такой класс (мало ли кому пригодится):

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
   public class AnsiString
    {
        private string value;
        public string Value { get { return value; } }
        public AnsiString(string _s)
        { value = _s; }

        public AnsiString(char[] _s)
        { value = new string(_s); }

        public static implicit operator AnsiString(string _str)
        {
            if (_str == null)
                return null;
            return new AnsiString(_str);
        }
        public static implicit operator AnsiString(char[] _charray)
        {
            if (_charray == null)
                return null;
            return new AnsiString(_charray);
        }

        public override string ToString()
        { return value; }

        public static implicit operator string(AnsiString _anstr)
        { return _anstr.value; }

        public static bool operator !=(AnsiString _left, AnsiString _right)
        { return _left.value != _right.value; }

        public static bool operator ==(AnsiString _left, AnsiString _right)
        { return _left.value == _right.value; }

        public int IndexOf(string _pattern)
        { return value.IndexOf(_pattern) + 1; }

        public int IndexOf(char _pattern, int _startindex)
        { return value.IndexOf(_pattern, _startindex - 1) + 1; }

        public int IndexOf(char _pattern)
        { return value.IndexOf(_pattern) + 1; }

        public string Remove(int startindex, int lenght)
        { return value.Remove(startindex - 1, lenght); }

        public string Substring(int startindex, int lenght)
        { return value.Substring(startindex - 1, lenght); }

        public static string StringReplace(string S, string OldPattern, string NewPattern)
        { return S.Replace(OldPattern, NewPattern); }

        public static string StringReplace(string S, char OldPattern, char NewPattern)
        { return S.Replace(OldPattern, NewPattern); }

        public string SetLength(int lenght)
        { return value.Substring(0, lenght); }

        public bool IsEmpty()
        { return string.IsNullOrEmpty(value); }
    }



Всем спасибо!
...
Рейтинг: 0 / 0
Класс AnsiString
    #38904083
Ilya81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть слабые места. Во-первых, попробуйте
Код: c#
1.
2.
if (someAnsiStringVariable != null)
  DoSomething();


Наверняка будет NullReferenceException. Во-вторых, попробуйте
Код: c#
1.
2.
3.
Dictionary<AnsiString, SomeOtherClass> dict = new Dictionary<AnsiString, SomeOtherClass>();
dict.Add("key1", new SomeOtherClass());
bool isItCorrect = dict.ContainsKey("key1");


Вероятно, значение переменной isItCorrect окажется неожидаемым. Рекомендую переопределить также методы Equals и GetHashCode.
...
Рейтинг: 0 / 0
Класс AnsiString
    #38904219
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Ку.Разобрался!
...
Всем спасибо!
Да пожалукста. Теперь ещё переделай в структуру и будет почти как должно бытъ.
...
Рейтинг: 0 / 0
Класс AnsiString
    #38904274
Алексей Ку.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikronАлексей Ку.Разобрался!
...
Всем спасибо!
Да пожалукста. Теперь ещё переделай в структуру и будет почти как должно бытъ.

А какой смысл переделывать в структуру?
...
Рейтинг: 0 / 0
Класс AnsiString
    #38904279
Алексей Ку.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ilya81Есть слабые места. Во-первых, попробуйте
Код: c#
1.
2.
if (someAnsiStringVariable != null)
  DoSomething();


Наверняка будет NullReferenceException. Во-вторых, попробуйте
Код: c#
1.
2.
3.
Dictionary<AnsiString, SomeOtherClass> dict = new Dictionary<AnsiString, SomeOtherClass>();
dict.Add("key1", new SomeOtherClass());
bool isItCorrect = dict.ContainsKey("key1");


Вероятно, значение переменной isItCorrect окажется неожидаемым. Рекомендую переопределить также методы Equals и GetHashCode.

Действительно получаю NullReferenceException. Есть какой-то стандартный алгоритм сравнения в таких случаях? Или мне как раз придётся определить Equals и использовать его?

Не совсем понял зачем мне GetHashCode, можете раскрыть чуть-чуть эту тему?
...
Рейтинг: 0 / 0
Класс AnsiString
    #38904286
Алексей Ку.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не могу понять как решить эту задачку.

Методы Equals у меня решарпер сам определил вот так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
        protected bool Equals(AnsiString _other)
        {
            return string.Equals(value, _other.value);
        }

        public override bool Equals(object _obj)
        {
            if (ReferenceEquals(null, _obj))
                return false;
            if (ReferenceEquals(this, _obj))
                return true;
            if (_obj.GetType() != GetType())
                return false;
            return Equals((AnsiString) _obj);
        }
...
Рейтинг: 0 / 0
Класс AnsiString
    #38904302
Ilya81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я б написал так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
public override bool Equals(object obj)
{
  AnsiString otherAnsiString = obj as AnsiString;
  if (otherAnsiString == null)
    return base.Equals(obj);
  return value == obj.value;
}

public static bool operator ==(AnsiString left, AnsiString right)
{
  if ((object)left == null &&  (object)right == null)
    return true;
  if ((object)left == null ||  (object)right == null)
    return false;
  return left.Equals(right);//чтоб не было дублирования кода
}

public static bool operator !=(AnsiString left, AnsiString right)
{
  if ((object)left == null &&  (object)right == null)
    return false;
  if ((object)left == null ||  (object)right == null)
    return true;
  return !left.Equals(right);
}
...
Рейтинг: 0 / 0
Класс AnsiString
    #38904314
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Ку.mikronпропущено...

Да пожалукста. Теперь ещё переделай в структуру и будет почти как должно бытъ.

А какой смысл переделывать в структуру?
Мне кажется ответ очевиден: еффективноть. Структуры передаются по значению и не требуют доп помять в хипе.
...
Рейтинг: 0 / 0
Класс AnsiString
    #38904315
Ilya81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про GetHashCode. Многие классы, в т. ч. Dictionary в целях оптимизации для поиска нужного элемента не сравнивают с каждым, а сравнивают сначала только результат функции GetHashCode. И только если GetHashCode вернул одинаковое значение, вызывают функцию Equals.

Рекомендую
Код: c#
1.
2.
3.
4.
public override int GetHashCode()
{
  return value == null ? 0 : value.GetHashCode();
}
...
Рейтинг: 0 / 0
Класс AnsiString
    #38904396
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikronМне кажется ответ очевиден: еффективноть. Структуры передаются по значению и не требуют доп помять в хипе.
И в результате сравнимый объем данных держат на стеке. Плюс - сразу же возникнет много нюансов, связанных с боксингом/анбоксингом. Я уже молчу про то, что единственное поле состояния в данном случае - класс, и лежать оно всё равно будет в хипе.
...
Рейтинг: 0 / 0
Класс AnsiString
    #38904405
Фотография Axeleron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныmikronМне кажется ответ очевиден: еффективноть. Структуры передаются по значению и не требуют доп помять в хипе.
И в результате сравнимый объем данных держат на стеке. Плюс - сразу же возникнет много нюансов, связанных с боксингом/анбоксингом. Я уже молчу про то, что единственное поле состояния в данном случае - класс, и лежать оно всё равно будет в хипе.

mikron уже давно пытается всех нас вышколить, чтобы поменяли философию на его ('правильную'). А пойти почитать, что Struct имеет смысл и эффективность для примитивных типов данных (value type типа int, double), а никак не reference (string, классы) ленится.
...
Рейтинг: 0 / 0
Класс AnsiString
    #38905937
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры ПавловныmikronМне кажется ответ очевиден: еффективноть. Структуры передаются по значению и не требуют доп помять в хипе.
И в результате сравнимый объем данных держат на стеке. Плюс - сразу же возникнет много нюансов, связанных с боксингом/анбоксингом. Я уже молчу про то, что единственное поле состояния в данном случае - класс, и лежать оно всё равно будет в хипе.
А спала Вера Павловна плохо и часто мучалась кошмарами.

Проверка фактов:
Код: c#
1.
2.
String SomeStringGenerator() { return DateTime.Now.ToString(); }
var myAnsiStr = new AnsiString(SomeStringGenerator());



В случае с классом имеем: 2 обьекта в хипе и один референс на стеке.
В случае со структурой: 1 обьект в хипе и опять-ж референс на стеке.
Сравниваем, что было-бы если бы использовалась нативная имплементация:
1 обьект в хипе и опять-ж референс на стеке.
Боксинг / унбоксинг вообще не нужен: т.к. структура не несёт никакой доп информации кроме референса на стринг,
при передаче обьекта всегда передавать стринг. Если кому не понятно, обьясняю на пальцах:
Код: c#
1.
2.
3.
4.
5.
var untypedArray = new Object[1];
var myAnsiStr = new AnsiString(SomeStringGenerator());
untypedArray[0] = myAnsiStr.Value;     // Do it this way
untypedArray[0] = (Object) myAnsiStr;  // Don't do it.
//  Or a better solution: define implicit operator Object which has to deliver internal Value.
...
Рейтинг: 0 / 0
Класс AnsiString
    #38905942
Фотография Axeleron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikron,
Код: c#
1.
2.
3.
untypedArray[0] = myAnsiStr.Value;
// эта операция идентична этой...
untypedArray[0] = (Object) myAnsiStr;
...
Рейтинг: 0 / 0
Класс AnsiString
    #38905944
Фотография Axeleron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Axeleron,

Отбой, пропустил что во второй строке нет .Value
...
Рейтинг: 0 / 0
Класс AnsiString
    #38905956
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Axeleronmikron уже давно пытается всех нас вышколить, чтобы поменяли философию на его ('правильную').
Давай я сам за себя скажу. Я пытаюсь донести до некоторых, что если недостоток в понимания материала вы пытаетесь заменить правилам, то разберитесь хоть в правилах и неверьте каждому написаному на заборе слову.
AxeleronА пойти почитать, что Struct имеет смысл и эффективность для примитивных типов данных (value type типа int, double), а никак не reference (string, классы) ленится.
"Чеку из гранаты не вынимать"
...
Рейтинг: 0 / 0
Класс AnsiString
    #38905960
Фотография Axeleron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MSDNDo not define a structure unless the type has all of the following characteristics:

It logically represents a single value, similar to primitive types (integer, double, and so on).
It has an instance size smaller than 16 bytes.
It is immutable.
It will not have to be boxed frequently.


А теперь навскидку из основ C# - является ли System.String immutable? И почему майкрософтовские идиоты решили создавать System.String как класс, а не структуру? Уверен, у Вас есть достойный ответ.
...
Рейтинг: 0 / 0
Класс AnsiString
    #38905962
Ilya81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Основной недостаток класса с точки зрения производительности - boxing/unboxing при обращении к вложенным value type. Основной недостаток структуры с точки зрения производительности - передача копии всей структуры при каждом вызове метода (если он не за'inline'ен). А дальше смотрим, что в среднем случается делать чаще.
...
Рейтинг: 0 / 0
Класс AnsiString
    #38905974
Фотография Axeleron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Запутал сам себя. Получается, что можно и Struct, если не будет проводиться боксинг/анбоксинг объекта AnsiString. Соглашаюсь с mikron.
...
Рейтинг: 0 / 0
Класс AnsiString
    #38905982
mikron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AxeleronMSDNDo not define a structure unless the type has all of the following characteristics:

It logically represents a single value, similar to primitive types (integer, double, and so on).
It has an instance size smaller than 16 bytes.
It is immutable.
It will not have to be boxed frequently.


А теперь навскидку из основ C# - является ли System.String immutable? И почему майкрософтовские идиоты решили создавать System.String как класс, а не структуру? Уверен, у Вас есть достойный ответ.

"А пойти почитать, что Struct имеет смысл и эффективность для примитивных типов данных (value type типа int, double), а никак не reference (string, классы) ленится."

1. Вот вы сами процетировали правило а про реферс я тут и не вижу. Доппридумывали?
2. Сделать структут immutable я бы тоже рекомендовал. Делу не помешает.
3. Вопрос не по адрессу. обратитесь с ним в микрософт.
...
Рейтинг: 0 / 0
Класс AnsiString
    #38905985
Фотография Axeleron
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikron,
Спокойствие. Чеку можете вставлять обратно в гранату
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Класс AnsiString
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]