zoukankan      html  css  js  c++  java
  • 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 获取页面元素的父元素,子元素。

    以上便是对泛型方法的总结,记录下来以便以后查阅.

  • 相关阅读:
    [SCOI2005]骑士精神
    [SCOI2005]超级格雷码
    [SDOI2013]淘金
    [SCOI2014]方伯伯的商场之旅
    P4317 花神的数论题
    RSA算法原理(一)
    PKI 笔记
    字符串解析运用-将字符串分解为多个整数,求各整数之和(华为oj)
    pycharm快捷键、常用设置、配置管理
    启动ipython notebook(jupyter)
  • 原文地址:https://www.cnblogs.com/bigbosscyb/p/13974253.html
Copyright © 2011-2022 走看看