Страницы

Поиск по вопросам

воскресенье, 2 февраля 2020 г.

c# переопределение ToString() для коллекции

#c_sharp #коллекции #переопределение


Как можно переопределить метод ToString() для коллекции?

List spisok = new List();
for (int i = 0; i < 20; i++)
     spisok.Add(new Place(PlaceStatus.Free));


Я хочу при вызове spisok.ToString() я получал String формата 0,0,0,0 (т.е. элементы
через запятую)

Или для такой коллекции аналогично

var spisok = new Place[20];
for (int i = 0; i < 20; i++)
     spisok[i] = new Place(PlaceStatus.Free));


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

    public enum PlaceStatus
    {
        Free,
        Booked,
        Paid,
        Confirmed
    }
    public class Place
    {
        public PlaceStatus Status { get; set; }

        public Place(PlaceStatus status)
        {
            Status = status;
        }

        public override string ToString()
        {
            return ((int)Status).ToString();
        }
    }

    


Ответы

Ответ 1



Создайте статический класс-helper. Это будет выглядеть примерно так: public static class PlaceCollectionHelper { public static string ToString(this IEnumerable Collection, string Separator) { return string.Join(Separator, Collection); } } И далее используйте в своём коде: string spisokStr = spisok.ToString(","); UPD: Предыдущий вариант является расширением, так как явно переопределить ToString() у существующей коллекции нельзя. Однако если Вам необходимо, чтобы сторонние методы могли вызывать нужное Вам преобразование Вашей коллекции в строку, придется создавать новый тип, который будет наследоваться от типа нужной Вам коллекции. Здесь есть 2 пути. Давайте рассмотрим их. 0) Самым лаконичным решением будет то, которое представлено в соседнем ответе: public class PlaceCollection : List { public override string ToString() { return string.Join(", ", this); } public string ToString(string Separator) { return string.Join(Separator, this); } } Вы просто создаете класс, который наследуется от листа с нужным Вам типом, где и переопределяете ToString() нужным Вам образом. Как Вы понимаете, работает эта конструкция точно так же, как и обычный лист: PlaceCollection collection = new PlaceCollection { new Place(PlaceStatus.Free), new Place(PlaceStatus.Booked) }; collection.Add(new Place(PlaceStatus.Paid)); Однако теперь, если Вы вызовете, скажем, Console.WriteLine, которая при передачи в нее объекта автоматически вызывает у него ToString(), то получите уже: Console.WriteLine(collection); // 0, 1, 2 1) Предыдущий вариант подойдет Вам лишь в том случае, если в качестве коллекции Вы используете List. Однако в Вашем втором примере ясно видно, что Вы так же используете и массив для своих целей. Так что в решении Вашей задаче нам поможет наследование от generic-интерфейса IEnumerable: public class PlaceCollection : IEnumerable { #region Var private IEnumerable Collection { get; set; } #endregion #region Init public PlaceCollection(IEnumerable Collection) { this.Collection = Collection; } public static implicit operator PlaceCollection(List Collection) { return new PlaceCollection(Collection); } public static implicit operator PlaceCollection(Place[] Collection) { return new PlaceCollection(Collection); } #endregion #region Functions public IEnumerator GetEnumerator() { return Collection.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return Collection.GetEnumerator(); } public override string ToString() { return string.Join(", ", Collection); } public string ToString(string Separator) { return string.Join(Separator, Collection); } #endregion } Доступ к элементам можно производить при помощи Linq, либо же дописать свои индексаторы. В данном классе реализовано неявное приведение, так что Вы вполне можете сделать так: Place[] placeArray = new Place[] { new Place(PlaceStatus.Free), new Place(PlaceStatus.Booked) }; PlaceCollection collection = placeArray; Или так: List placeList = new List { new Place(PlaceStatus.Free), new Place(PlaceStatus.Booked) }; PlaceCollection collection = placeList; Однако результат все равно будет один: Console.WriteLine(collection); // 0, 1 И так как наследовались мы от IEnumerable, то Вам доступно получение энумератора: foreach (Place p in collection) Console.WriteLine(p); // 0 // 1 Выбирайте наиболее удобный Вам метод и удачи в Ваших решениях)

Ответ 2



public class MyTypeList : List { public override string ToString() { return ... } }

Комментариев нет:

Отправить комментарий