Еще одно важное различие: typedef
с не может быть вперед объявлена. Таким образом для typedef
опция Вы должны #include
файл, содержащий эти typedef
, имея в виду все, что #include
с Ваш .h
также включает тот файл, нужен ли этому непосредственно он или не и так далее. Это может определенно повлиять на Ваше время изготовления на большие проекты.
Без эти typedef
, в некоторых случаях можно просто добавить предописание struct Foo;
наверху Вашего .h
файл и только #include
определение структуры в Вашем .cpp
файл.
Вам нужно создать подкласс, чтобы переопределить любой метод. Смысл дженериков состоит в том, чтобы сказать, что вы хотите одного и того же поведения независимо от типа T. Если вам нужно другое поведение для определенного типа T, вы нарушаете этот контракт и вам нужно будет написать свой собственный класс:
public class MyTypeList : List<MyClass>
{
public override string ToString()
{
return ...
}
}
Отредактировано для добавления:
Нет, вы не можете переопределить метод, создав расширение, но вы можете создать новый метод с другой сигнатурой, которая характерна для этого типа списка:
public static string ExtendedToString(this List<MyClass> list)
{
return ....
}
Используется с
List<MyClass> myClassList = new List<MyClass>
string output = myClassList.ExtendedToString();
Я все еще думаю вам лучше создать подкласс ...
Возможно, немного не по теме, но я использую метод расширения ToDelimitedString
, который работает для любого IEnumerable
. Вы можете (необязательно) указать используемый разделитель и делегата для выполнения настраиваемого преобразования строки для каждого элемента:
// if you've already overridden ToString in your MyClass object...
Console.WriteLine(list.ToDelimitedString());
// if you don't have a custom ToString method in your MyClass object...
Console.WriteLine(list.ToDelimitedString(x => x.Property1 + "-" + x.Property2));
// ...
public static class MyExtensionMethods
{
public static string ToDelimitedString<T>(this IEnumerable<T> source)
{
return source.ToDelimitedString(x => x.ToString(),
CultureInfo.CurrentCulture.TextInfo.ListSeparator);
}
public static string ToDelimitedString<T>(
this IEnumerable<T> source, Func<T, string> converter)
{
return source.ToDelimitedString(converter,
CultureInfo.CurrentCulture.TextInfo.ListSeparator);
}
public static string ToDelimitedString<T>(
this IEnumerable<T> source, string separator)
{
return source.ToDelimitedString(x => x.ToString(), separator);
}
public static string ToDelimitedString<T>(this IEnumerable<T> source,
Func<T, string> converter, string separator)
{
return string.Join(separator, source.Select(converter).ToArray());
}
}
Вам нужно будет создать свой собственный класс, унаследованный от Collection, а затем специально переопределить метод ToString () этого класса.
В зависимости от точной причины, по которой вы хотите переопределить List
, чтобы вернуть что-то конкретное, может быть полезно взглянуть на custom TypeConverter
реализации.
Если вы просто хотите, чтобы List
определенных T
отображался определенным образом в виде строки
в местах, где используются TypeConverters, например, в отладчике или в string.Format ("List: {0}", listVariable)
типов ситуаций, этого может быть достаточно.
Возможно, вы только что видели результат того, что где-то отображается ToString (), и он хотел изменить это, не зная о существовании TypeConverter
и местах, где они используются.Я считаю, что многие / большинство / все (не уверены, какие?) Преобразователей типов по умолчанию в .NET Framework просто используют ToString () при преобразовании любого типа, для которого они определены, в строку
.
Нет, это невозможно. ToString из TList предоставит вам строковое представление объекта списка.
Возможные варианты:
Надеюсь, это поможет!
Если ваш метод должен называться ToString
, вам нужно будет получить класс из List
. Вы можете сделать его универсальным:
static class MyList<T> : List<T>
{
public override string ToString()
{
// ...
}
}
В этом случае вам нужно будет использовать MyList
вместо List
во всем приложении, если вы хотите иметь собственное преобразование.
Однако, если вы можете выбрать другое имя для своего метода, вы можете использовать методы расширения и добиться того же эффекта, почти не изменяя код:
Вы можете использовать методы расширения, чтобы сделать его более общим:
static class ListExtension
{
public static void ConvertToString<T>(this IEnumerable<T> items)
{
// ...
}
}
Вы можно использовать его с любым экземпляром IEnumerable
, как если бы это был обычный метод:
List<MyClass> list = new List<MyClass> { ... };
Console.WriteLine(list.ConvertToString());
int[] array_of_ints = {1,2,3,4,5};
Console.WriteLine(array_of_ints.ConvertToString());