2009-03-28 2 views
27

Каковы некоторые примеры использования генераторов в C#/VB.NET и почему вы хотите использовать дженерики?Примеры использования Generics в .Net (C#/VB.NET)

+4

Этот вопрос является слишком общим –

+0

Вы говорите о открытых дженериков или закрытых дженериков? В основном, как бы «использовать» их или как «сделать» их? или оба? – Joseph

+0

что sambo99 сказал - ТАК нужен «слишком расплывчатый», чтобы дополнить «слишком локализованным» – annakata

ответ

60

Просто, вы объявляете тип или метод с дополнительными тегами, чтобы указать общие биты:

class Foo<T> { 
    public Foo(T value) { 
     Value = value; 
    } 
    public T Value {get;private set;} 
} 

выше определяет общий тип Foo «из T», где T предоставляется вызывающей стороной. По соглашению, аргументы родового типа начинаются с T. Если есть только один, T прекрасно - иначе назвать их все с пользой: TSource, TValue, TListType и т.д.

В отличие от шаблонов C++, .NET дженерики предоставляются во время выполнения (не трюки компилятора). Например:

Foo<int> foo = new Foo<int>(27); 

Все T s были заменены int в выше. При необходимости, вы можете ограничить общие аргументы с ограничениями:

class Foo<T> where T : struct {} 

Теперь Foo<string> откажется компилировать - в string не структура (значение типа). Допустимые ограничения:

T : class // reference-type (class/interface/delegate) 
T : struct // value-type except Nullable<T> 
T : new() // has a public parameterless constructor 
T : SomeClass // is SomeClass or inherited from SomeClass 
T : ISomeInterface // implements ISomeInterface 

Ограничения также может включать в себя другие аргументы шаблонного типа, например:

T : IComparable<T> // or another type argument 

Вы можете иметь столько общие аргументы, как вам нужно:

public struct KeyValuePair<TKey,TValue> {...} 

Другие вещи Примечание:

  • s tatic и т. д. определены на комбинацию общего типа - поэтому статическое поле на Foo<int> является отдельным для него на Foo<float>.
  • методы могут быть обобщенными слишком - попытаться избежать, используя те же имена, как класс используется, так как вы не сможете неоднозначность
  • вложенных типов наследуют общие типы от своих родителей

, например, :

class Foo<T> { 
    class Bar<TInner> {} // is effectively Bar<T,TInner>, for the outer T 
} 
+0

Отличный ответ. Из любопытства (новичок в дженериках) - почему мы должны включать сразу после названия класса? –

+0

@ JᴀʏMᴇᴇ используется в качестве заполнителя до тех пор, пока определение не будет подключено. –

+1

@ JᴀʏMᴇᴇ это может быть '' если вам нравится; «T» - это просто конвенция для «вещи, в которой она является общей»; поэтому 'List ' - это список элементов типа 'T', например; «Словарь » - это словарь с ключами типа «TKey» и значениями типа «TValue» –

6

Пример 1: Вы хотите, чтобы создать тройной класс

Class Triple<T1, T2, T3> 
{ 
    T1 _first; 
    T2 _second; 
    T3 _Third; 
} 

Exa mple 2: Вспомогательный класс, который будет анализировать любое значение перечисления для данного типа данных

static public class EnumHelper<T> 
{ 
    static public T Parse(string value) 
    { 
     return (T)Enum.Parse(typeof(T), value); 
    } 
} 
3

Наиболее распространенные причины и случаи использования для генериков описаны в документации MSDN, упомянутой ранее. Одно из преимуществ дженериков, которые я хотел бы добавить, заключается в том, что они могут улучшить поддержку инструмента в процессе разработки. Инструменты рефакторинга, такие как интегрированные в Visual Studio или ReSharper, основаны на анализе статического типа для предоставления помощи при кодировании.Поскольку генераторы обычно добавляют больше информации о типе к вашей объектной модели, есть больше информации для таких инструментов для анализа и для помощи в кодировании.

На концептуальном уровне дженерики помогают решать «сквозные» проблемы независимо от области вашего приложения. Независимо от того, разрабатываете ли вы финансовое приложение или книжный магазин, вам рано или поздно нужно будет хранить коллекции вещей, будь то счета, книги или что-то еще. Реализация таких коллекций, как правило, мало что знает о вещах, которые должны храниться в этих коллекциях. Следовательно, общие коллекции, поставляемые с платформой .NET, являются основным примером использования предикатов.

4

Одно общее и чрезвычайно полезное использование дженериков - это строго типизированные классы коллекций. Традиционно всем классам коллекции пришлось передавать объекты и возвращать объекты при запросе. Вы должны были обработать все преобразования типов самостоятельно. С дженериками вам не обязательно это делать. Вы можете иметь List (Of Integer), и когда вы запрашиваете значения из него, вы получите целые числа. Вы не получите объекты, которые затем вам нужно преобразовать в целые числа.

3
private void button1_Click_1(object sender, RoutedEventArgs e) 
    { 
     TextValue<string, int> foo = new TextValue<string, int>("",0); 
     foo.Text = "Hi there"; 
     foo.Value = 3995; 
     MessageBox.Show(foo.Text); 
    } 

    class TextValue<TText, TValue> 
    { 
     public TextValue(TText text, TValue value) 
     { 
      Text = text; 
      Value = value; 
     } 
     public TText Text { get; set; } 
     public TValue Value { get; set; } 
    } 
0
private void button1_Click_1(object sender, RoutedEventArgs e) 
    { 
     TextValue<string, int> foo; 
     List<TextValue<string, int>> listTextValue = new List<TextValue<string, int>>(); 
     for (int k = 0; k < 5; ++k) 
     { 
      foo = new TextValue<string, int>("",0); 
      foo.Text = k.ToString(); 
      foo.Value = k; 
      listTextValue.Add(foo); 
      otherList. 
      MessageBox.Show(foo.Text); 
     } 

    } 

    class TextValue<TText, TValue> 
    { 
     public TextValue(TText text, TValue value){Text = text; Value = value;} 
     public TText Text { get; set; } 
     public TValue Value { get; set; } 
    } 
1

Основным примером будет:

class Other{ 
class Generic<T> 
{ 
    void met1(T x); 
} 
static void Main() 
{ 
    Generic<int> g = new Generic<int>(); 
    Generic<string> s = new Generic<string>(); 
} 
} 
Смежные вопросы