【发布时间】:2009-03-28 10:06:58
【问题描述】:
在 C#/VB.NET 中使用泛型的例子有哪些?为什么要使用泛型?
【问题讨论】:
-
这个问题太笼统了
-
你说的是开放泛型还是封闭泛型?主要是,如何“使用”它们或如何“制造”它们?还是两者兼而有之?
-
sambo99 所说的 - 所以需要一个“过于模糊”来补充“过于本地化”
在 C#/VB.NET 中使用泛型的例子有哪些?为什么要使用泛型?
【问题讨论】:
简单地说,你用额外的标签声明一个类型或方法来指示通用位:
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<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> {...}
其他注意事项:
Foo<int> 上的静态字段与Foo<float> 上的静态字段是分开的。例如:
class Foo<T> {
class Bar<TInner> {} // is effectively Bar<T,TInner>, for the outer T
}
【讨论】:
<FiddleSticks>; T 只是“通用的东西”的约定;例如,List<T> 是 T 类型的元素列表; Dictionary<TKey, TValue> 是一个字典,其键类型为 TKey,值类型为 TValue
示例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);
}
}
【讨论】:
泛型的一个常见且非常有用的用法是强类型集合类。传统上,所有集合类都必须传递对象,并在查询时返回对象。您必须自己处理所有类型转换。使用泛型,您不必这样做。你可以有 List(Of Integer),当你从它请求值时,你会得到整数。您不会得到必须转换为整数的对象。
【讨论】:
前面提到的 MSDN 文档中描述了泛型的最常见原因和用例。我想补充的泛型的一个好处是它们可以增强开发过程中的工具支持。诸如集成在 Visual Studio 或 ReSharper 中的重构工具依赖于静态类型分析来在编码时提供帮助。由于泛型通常会向您的对象模型添加更多类型信息,因此此类工具有更多信息可以分析并帮助您编码。
在概念层面上,泛型可帮助您独立于应用程序域解决“横切”问题。无论您是在开发金融应用程序还是书店,您迟早都需要维护收藏品,无论是账户、书籍还是其他任何东西。此类集合的实现通常需要对这些集合中要维护的内容知之甚少。因此,.NET 框架附带的泛型集合是泛型用例的主要示例。
【讨论】:
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; }
}
【讨论】:
一个基本的例子是:
class Other{
class Generic<T>
{
void met1(T x);
}
static void Main()
{
Generic<int> g = new Generic<int>();
Generic<string> s = new Generic<string>();
}
}
【讨论】:
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; }
}
【讨论】: