泛型
<h3>泛型方法:调用方法指定类型,必须和传入参数类型一致</h3>
<pre><code class="language-csharp">public static void show&lt;T&gt;(T Tvalue)
{
console.write(&quot;Hello&quot;);
}</code></pre>
<h3>泛型类</h3>
<pre><code class="language-csharp">public class show&lt;T&gt;
{
console.write(&quot;Hello&quot;);
}</code></pre>
<h3>泛型接口</h3>
<pre><code class="language-csharp">public interface show&lt;T&gt;
{
console.write(&quot;Hello&quot;);
}</code></pre>
<h3>泛型委托</h3>
<pre><code class="language-csharp">public delegate void show&lt;T&gt;(T Tvalue)
{
console.write(&quot;Hello&quot;);
}</code></pre>
<h3>泛型缓存:每一个新的类型生成一新的个副本</h3>
<pre><code class="language-csharp"> public class GenericCache&lt;T&gt;
{
private static Dictionary&lt;string, T&gt; _cache = new Dictionary&lt;string, T&gt;();
public static void Add(string key, T value)
{
_cache[key] = value;
}
public static T Get(string key)
{
return _cache.ContainsKey(key) ? _cache[key] : default(T);
}
}
// 使用 int 类型
GenericCache&lt;int&gt;.Add(&quot;one&quot;, 1);
int value1 = GenericCache&lt;int&gt;.Get(&quot;one&quot;);
// 使用 string 类型
GenericCache&lt;string&gt;.Add(&quot;hello&quot;, &quot;world&quot;);
string value2 = GenericCache&lt;string&gt;.Get(&quot;hello&quot;);</code></pre>
<p>在上面的例子中,<code>GenericCache&lt;int&gt;</code> 和 <code>GenericCache&lt;string&gt;</code> 是两个不同的类型,它们各自有自己的静态字段 <code>_cache</code>。</p>
<h3>泛型约束:</h3>
<h4>1. 基类约束</h4>
<p>基类约束要求类型参数必须是指定基类或派生自指定基类。</p>
<pre><code class="language-csharp"> public class BaseClass { }
public class DerivedClass : BaseClass { }
public class GenericClass&lt;T&gt; where T : BaseClass
{
public void Display(T obj)
{
Console.WriteLine(obj.GetType().Name);
}
}
// 只能使用 BaseClass 或其派生类
var obj = new GenericClass&lt;DerivedClass&gt;();
obj.Display(new DerivedClass());</code></pre>
<h4>2. 接口约束</h4>
<p>接口约束要求类型参数必须实现指定的接口。</p>
<pre><code>```csharp
public interface IMyInterface
{
void MyMethod();
}
public class MyClass : IMyInterface
{
public void MyMethod()
{
Console.WriteLine(&quot;MyMethod implemented&quot;);
}
}
public class GenericClass&lt;T&gt; where T : IMyInterface
{
public void CallMyMethod(T obj)
{
obj.MyMethod();
}
}
// 只能使用实现了 IMyInterface 的类型
var obj = new GenericClass&lt;MyClass&gt;();
obj.CallMyMethod(new MyClass());
```</code></pre>
<h4>3. 值类型约束</h4>
<p>值类型约束要求类型参数必须是值类型(如 <code>int</code>、<code>struct</code> 等)。</p>
<pre><code>```csharp
public class GenericClass&lt;T&gt; where T : struct
{
public T Add(T a, T b)
{
dynamic da = a;
dynamic db = b;
return da + db;
}
}
// 只能使用值类型
var obj = new GenericClass&lt;int&gt;();
Console.WriteLine(obj.Add(1, 2));
```</code></pre>
<h4>4. 引用类型约束</h4>
<p>引用类型约束要求类型参数必须是引用类型(如 <code>class</code>、<code>interface</code> 等)。</p>
<pre><code class="language-csharp">public class GenericClass&lt;T&gt; where T : class
{
public T CreateInstance()
{
return Activator.CreateInstance&lt;T&gt;();
}
}
// 只能使用引用类型
var obj = new GenericClass&lt;MyClass&gt;();
Console.WriteLine(obj.CreateInstance().GetType().Name);</code></pre>
<h4>5. 枚举约束(C# 7.3 及以后版本)</h4>
<p>枚举约束要求类型参数必须是枚举类型。</p>
<pre><code class="language-csharp">public class GenericClass&lt;T&gt; where T : Enum
{
public void DisplayEnumValues()
{
foreach (var value in Enum.GetValues(typeof(T)))
{
Console.WriteLine(value);
}
}
}
public enum Colors { Red, Green, Blue }
// 只能使用枚举类型
var obj = new GenericClass&lt;Colors&gt;();
obj.DisplayEnumValues();</code></pre>
<h4>6. 无参构造函数约束</h4>
<p>无参构造函数约束要求类型参数必须有一个无参的构造函数。</p>
<pre><code class="language-csharp"> public class GenericClass&lt;T&gt; where T : new()
{
public T CreateInstance()
{
return new T();
}
}
public class MyClass
{
public MyClass() { }
}
// 只能使用有无参构造函数的类型
var obj = new GenericClass&lt;MyClass&gt;();
Console.WriteLine(obj.CreateInstance().GetType().Name);</code></pre>