Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Класс AnsiString / 24 сообщений из 24, страница 1 из 1
13.03.2015, 14:48
    #38903957
Алексей Ку.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
Добрый день, знатоки!

Я всё-таки взялся за реализацию класса 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
13.03.2015, 15:00
    #38903985
Axeleron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
Алексей Ку.Вопрос: как мне сделать неявную конвертацию к строке. Т.е. я хочу выполнять след операции:
Код: c#
1.
2.
3.
AnsiString a = "asd";

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



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

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


Алексей Ку.делать, чтобы в Debug режиме, при наведении на переменную типа AnsiString, мне показывалось сразу его value. Ну т.е. как и у класса String.
Переопределить метод ToString.
...
Рейтинг: 0 / 0
13.03.2015, 15:26
    #38904042
Алексей Ку.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
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
13.03.2015, 15:32
    #38904059
Алексей Ку.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс 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.
   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
13.03.2015, 15:43
    #38904083
Ilya81
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
Есть слабые места. Во-первых, попробуйте
Код: 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
13.03.2015, 16:49
    #38904219
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
Алексей Ку.Разобрался!
...
Всем спасибо!
Да пожалукста. Теперь ещё переделай в структуру и будет почти как должно бытъ.
...
Рейтинг: 0 / 0
13.03.2015, 17:14
    #38904274
Алексей Ку.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
mikronАлексей Ку.Разобрался!
...
Всем спасибо!
Да пожалукста. Теперь ещё переделай в структуру и будет почти как должно бытъ.

А какой смысл переделывать в структуру?
...
Рейтинг: 0 / 0
13.03.2015, 17:16
    #38904279
Алексей Ку.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
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
13.03.2015, 17:19
    #38904286
Алексей Ку.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
Не могу понять как решить эту задачку.

Методы 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
13.03.2015, 17:29
    #38904302
Ilya81
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс 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.
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
13.03.2015, 17:34
    #38904314
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
Алексей Ку.mikronпропущено...

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

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

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

mikron уже давно пытается всех нас вышколить, чтобы поменяли философию на его ('правильную'). А пойти почитать, что Struct имеет смысл и эффективность для примитивных типов данных (value type типа int, double), а никак не reference (string, классы) ленится.
...
Рейтинг: 0 / 0
16.03.2015, 14:34
    #38905937
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
Сон Веры Павловны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
16.03.2015, 14:38
    #38905942
Axeleron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
mikron,
Код: c#
1.
2.
3.
untypedArray[0] = myAnsiStr.Value;
// эта операция идентична этой...
untypedArray[0] = (Object) myAnsiStr;
...
Рейтинг: 0 / 0
16.03.2015, 14:39
    #38905944
Axeleron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
Axeleron,

Отбой, пропустил что во второй строке нет .Value
...
Рейтинг: 0 / 0
16.03.2015, 14:47
    #38905956
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
Axeleronmikron уже давно пытается всех нас вышколить, чтобы поменяли философию на его ('правильную').
Давай я сам за себя скажу. Я пытаюсь донести до некоторых, что если недостоток в понимания материала вы пытаетесь заменить правилам, то разберитесь хоть в правилах и неверьте каждому написаному на заборе слову.
AxeleronА пойти почитать, что Struct имеет смысл и эффективность для примитивных типов данных (value type типа int, double), а никак не reference (string, классы) ленится.
"Чеку из гранаты не вынимать"
...
Рейтинг: 0 / 0
16.03.2015, 14:56
    #38905960
Axeleron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
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
16.03.2015, 14:57
    #38905962
Ilya81
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
Основной недостаток класса с точки зрения производительности - boxing/unboxing при обращении к вложенным value type. Основной недостаток структуры с точки зрения производительности - передача копии всей структуры при каждом вызове метода (если он не за'inline'ен). А дальше смотрим, что в среднем случается делать чаще.
...
Рейтинг: 0 / 0
16.03.2015, 15:04
    #38905974
Axeleron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
Запутал сам себя. Получается, что можно и Struct, если не будет проводиться боксинг/анбоксинг объекта AnsiString. Соглашаюсь с mikron.
...
Рейтинг: 0 / 0
16.03.2015, 15:10
    #38905982
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
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
16.03.2015, 15:12
    #38905985
Axeleron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Класс AnsiString
mikron,
Спокойствие. Чеку можете вставлять обратно в гранату
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Класс AnsiString / 24 сообщений из 24, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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