C#:泛型方法
在上一篇讲了泛型的基本概念后,本篇将走进泛型的应用。
泛型方法:
第一步:声明泛型方法
- 方法名后面使用<>,然后在<>中放置类型参数列表
- 在方法的参数列表中,使用类型参数
- 在方法参数列表后,使用约束子句(这一步不是必选的)
/// <summary>
/// 比较两个数的大小
/// </summary>
/// <typeparam name="TTT">实现了ICompare接口的任何类型</typeparam>
/// <param name="tT1"></param>
/// <param name="tT2"></param>
/// <returns>若tT1<tT2则返回true,否则返回false</returns>
static bool IsLessThan<TTT>(TTT tT1, TTT tT2) where TTT : IComparable
{
return tT1.CompareTo(tT2) < 0 ? true : false;
}
第二步:调用泛型方法---要调用泛型方法,就要在调用时提供类型实参
static void Main(string[] args)
{
bool isLessThan1 = IsLessThan<int>(12, 11);
Console.WriteLine(isLessThan1);
bool isLessThan2 = IsLessThan<int>(1, 11);
Console.WriteLine(isLessThan2);
Console.ReadLine();
}
/*
运行结果:
False
True
*/
泛型方法具有类型推断能力
当我们调用方法时,编译器由传入的实参的类型能够推断出类型参数的类型,所以调用泛型方法时可以不写"<类型参数>"
通过实战练习使用泛型方法
首先是WPF的XAML布局文件
<Window x:Class="VisualTreeSearch.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:VisualTreeSearch"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid x:Name="outergrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Slider Maximum="100" Minimum="0" Value="20" ValueChanged="Slider_ValueChanged"/>
<ContentControl x:Name="rgbControl" Grid.Row="1">
<ContentControl.Template>
<ControlTemplate>
<StackPanel>
<RadioButton x:Name="red" Foreground="Red" Content="红灯" GroupName="rgb"/>
<RadioButton x:Name="green" Foreground="Green" Content="绿灯" GroupName="rgb"/>
<RadioButton x:Name="yellow" Foreground="Yellow" Content="黄灯" GroupName="rgb"/>
</StackPanel>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
</Grid>
</Window>
界面截图
- 需求:通过拖动滑块,滑块的值从左到右慢慢在增大;当滑块的值增大过程中黄、绿、红单选按钮依次被选中。
- 问题是:由于RadioButton是装在控件模板中的,所以无法在XAML文件对应的.cs文件中直接通过控件的Name操作RadioButton。
- 分析:根据控件名获取子控件是一个共性的问题,即:写出一个通用方法,它能够接受一个要查找的子控件的name和子控件所在的父控件的实例;通过执行一系操作最终给返回一个子控件实例。
所以,最终的解决方案时:定义一个泛型方法---可从指定控件中查找到目标子控件;且在定义泛型方法时不用在意将要查找的控件的具体类型(因为该类型会被类型参数占据)。
- 定义泛型方法(可以将本方法定义在一个独立的cs文件中,让此方法能够成为你项目中的工具方法)
/// 查找子元素
/// </summary>
/// <typeparam name="T">子元素类型</typeparam>
/// <param name="obj">父元素</param>
/// <param name="name">子元素name</param>
/// <returns>若查找到子元素则返回子元素类型实例;否则返回null值</returns>
public static T GetChildObject<T>(DependencyObject obj, string name) where T : FrameworkElement
{
DependencyObject child = null;
T grandChild = null;
for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
{
child = VisualTreeHelper.GetChild(obj, i);
if (child is T && (((T)child).Name == name | string.IsNullOrEmpty(name)))
{
return (T)child;
}
else
{
grandChild = GetChildObject<T>(child, name);
if (grandChild != null)
return grandChild;
}
}
return null;
}
- 根据滑块的值的变化,操作RadioButton的选中状态
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (rgbControl != null)
{
RadioButton radioButton;
if (e.NewValue < 40)
{
radioButton = MyVisualTreeHelper.GetChildObject<RadioButton>(rgbControl, "yellow");
}
else if (e.NewValue < 80)
{
radioButton = MyVisualTreeHelper.GetChildObject<RadioButton>(rgbControl, "green");
}
else
{
radioButton = MyVisualTreeHelper.GetChildObject<RadioButton>(rgbControl, "red");
}
if (radioButton != null)
{
radioButton.IsChecked = true;
}
}
e.Handled = true;
}
- 运行效果
关于类似的需要查找所以目标类型的子控件、以及查找目标类型的父控件的扩展方法请看这篇博客:Wpf 获取页面元素的父元素,子元素。
以上便是对泛型方法的总结,记录下来以便以后查阅.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异