【问题标题】:Examples of usage of Generics in .Net (C#/VB.NET) [closed].Net(C#/VB.NET)中泛型的使用示例[关闭]
【发布时间】:2009-03-28 10:06:58
【问题描述】:

在 C#/VB.NET 中使用泛型的例子有哪些?为什么要使用泛型?

【问题讨论】:

  • 这个问题太笼统了
  • 你说的是开放泛型还是封闭泛型?主要是,如何“使用”它们或如何“制造”它们?还是两者兼而有之?
  • sambo99 所说的 - 所以需要一个“过于模糊”来补充“过于本地化”

标签: c# .net vb.net generics


【解决方案1】:

简单地说,你用额外的标签声明一个类型或方法来指示通用位:

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);

以上所有Ts 都已替换为int。如有必要,您可以使用约束来限制泛型参数:

class Foo<T> where T : struct {}

现在Foo&lt;string&gt; 将拒绝编译 - 因为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> {...}

其他注意事项:

  • 静态成员等是根据泛型类型组合定义的 - 因此Foo&lt;int&gt; 上的静态字段与Foo&lt;float&gt; 上的静态字段是分开的。
  • 方法也可以是通用的 - 尽量避免使用与类使用相同的名称,因为您将无法消除歧义
  • 嵌套类型从其父类继承泛型类型

例如:

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

【讨论】:

  • 很好的答案。出于好奇(泛型新手) - 为什么我们必须在类名之后包含 ?
  • @JᴀʏMᴇᴇ 用作占位符,直到定义被连接起来
  • @JᴀʏMᴇᴇ 如果你愿意,它可以是&lt;FiddleSticks&gt;; T 只是“通用的东西”的约定;例如,List&lt;T&gt; 是 T 类型的元素列表; Dictionary&lt;TKey, TValue&gt; 是一个字典,其键类型为 TKey,值类型为 TValue
  • 直到今天的复兴,我才完全忘记了这个线程。从那以后,我经常使用泛型,但仍然感谢您的回复 - 我相信它们对于有相同问题的其他人会很方便。
【解决方案2】:

示例1:你想创建三元类

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

示例 2:一个帮助类,它将解析给定数据类型的任何枚举值

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

【讨论】:

    【解决方案3】:

    泛型的一个常见且非常有用的用法是强类型集合类。传统上,所有集合类都必须传递对象,并在查询时返回对象。您必须自己处理所有类型转换。使用泛型,您不必这样做。你可以有 List(Of Integer),当你从它请求值时,你会得到整数。您不会得到必须转换为整数的对象。

    【讨论】:

      【解决方案4】:

      前面提到的 MSDN 文档中描述了泛型的最常见原因和用例。我想补充的泛型的一个好处是它们可以增强开发过程中的工具支持。诸如集成在 Visual Studio 或 ReSharper 中的重构工具依赖于静态类型分析来在编码时提供帮助。由于泛型通常会向您的对象模型添加更多类型信息,因此此类工具有更多信息可以分析并帮助您编码。

      在概念层面上,泛型可帮助您独立于应用程序域解决“横切”问题。无论您是在开发金融应用程序还是书店,您迟早都需要维护收藏品,无论是账户、书籍还是其他任何东西。此类集合的实现通常需要对这些集合中要维护的内容知之甚少。因此,.NET 框架附带的泛型集合是泛型用例的主要示例。

      【讨论】:

        【解决方案5】:
            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; }
            }
        

        【讨论】:

          【解决方案6】:

          一个基本的例子是:

          class Other{
           class Generic<T>
          {
            void met1(T x);
          }
          static void Main()
          {
            Generic<int> g = new Generic<int>();
            Generic<string> s = new Generic<string>();
          }
          }
          

          【讨论】:

            【解决方案7】:
                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; }
                }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-05-14
              • 1970-01-01
              • 1970-01-01
              • 2010-10-17
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多