C#编码实践:使用委托和特性调用指定函数

建立一个C#控制台应用程序AttributeTest。

建立一个类Operations,代码如下:

namespace AttributeTest
{
    public class Operations
    {
        public static int Add(int a, int b) { return a + b; }
        public static int Minus(int a, int b) { return a - b; }
        public static int Multiply(int a, int b) { return a * b; }
        public static int Divide(int a, int b) { return a / b; }
        public static int Modulo(int a, int b) { return a % b; }
    }
}

一种调用指定函数的方式,是建立一个函数UseOperation2和一个委托。将要调用的Operations内函数作为参数传入到UseOperation2中:

public delegate TOutput OperDelegate<TInput, TOutput>(TInput input1, TInput input2);

public static void UseOperation2<TInput, TOutput>(
    OperDelegate<TInput, TOutput> operDelegate, TInput input1, TInput input2)
{
    TOutput output = operDelegate(input1, input2); 
    Console.WriteLine(string.Format("{0} {1} {2} = {3}",
        input1, operDelegate.Method.Name, input2, output));
}

在Main函数内写如下代码:

Console.WriteLine("调用Operations类内各函数:");
UseOperation2(Operations.Add, 3, 5);
UseOperation2(Operations.Minus, 9, 4);
UseOperation2(Operations.Multiply, 3, 7);
UseOperation2(Operations.Divide, 8, 2);
UseOperation2(Operations.Modulo, 15, 4);

输出结果如下:

223903_TauM_1425762.png

如果不想以函数作为参数传递,还可以通过为Operations类内的函数添加特性来解决这一问题。

建立一个特性类OperateAttribute:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AttributeTest
{
    /// <summary>
    /// 运算特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Method)]
    public class OperateAttribute : Attribute
    {
        /// <summary>
        /// 运算特性
        /// </summary>
        /// <param name="operateNo">运算代号</param>
        public OperateAttribute(string operateNo)
        {
            this.operateNo = operateNo;
        }

        /// <summary>
        /// 运算代号
        /// </summary>
        string operateNo;
        /// <summary>
        /// 运算代号
        /// </summary>
        public string OperNo
        {
            get
            {
                return operateNo;
            }
        }
    }
}

这个时候需要修改一下Operations类下个函数,为它们逐个添加刚刚实现的特性Operate:

namespace AttributeTest
{
    public class Operations
    {
        [Operate("ADD")]
        public static int Add(int a, int b) { return a + b; }

        [Operate("MINUS")]
        public static int Minus(int a, int b) { return a - b; }

        [Operate("MULTIPLY")]
        public static int Multiply(int a, int b) { return a * b; }

        [Operate("DIVIDE")]
        public static int Divide(int a, int b) { return a / b; }

        [Operate("MOD")]
        public static int Modulo(int a, int b) { return a % b; }
    }
}

要反射标记了我们指定特性的函数的细节,可以在Main方法旁边实现如下函数:

/// <summary>
/// 打印Operations类内各函数属性
/// </summary>
public static void PrintOperations()
{
    foreach (MethodInfo mInfo in (new Operations()).GetType().GetMethods())
    {
        foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo))
        {
            if (attr is OperateAttribute)
            {
                string operNo = (attr as OperateAttribute).OperNo;
                Console.WriteLine("=====================");
                Console.WriteLine("关联属性:" + mInfo.Attributes);
                Console.WriteLine("函数名称:" + mInfo.Name);
                Console.WriteLine("成员类型:" + mInfo.MemberType);
                Console.WriteLine("参数0类型:" + mInfo.GetParameters()[0].ParameterType.ToString());
                Console.WriteLine("参数1类型:" + mInfo.GetParameters()[1].ParameterType.ToString());
                Console.WriteLine("返回值类型:" + mInfo.ReturnParameter.ParameterType.ToString());
            }
        }
    }
}

在Main方法中添加代码:

Console.WriteLine("打印Operations类内各函数属性:");
PrintOperations();

输出结果如下:

224543_DQcv_1425762.png

要通过指定Operate特性值来决定调用哪个函数,可以在Main方法旁边实现如下函数:

/// <summary>
/// 调用Operations类内各函数
/// </summary>
/// <param name="operNo">运算代号</param>
/// <param name="a">运算符a</param>
/// <param name="b">运算符b</param>
public static void UseOperation(string operNo, int a, int b)
{
    foreach (MethodInfo mInfo in (new Operations()).GetType().GetMethods())
    {
        foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo))
        {
            if (attr is OperateAttribute && 
                (attr as OperateAttribute).OperNo == operNo)
            {
                Console.WriteLine(string.Format("{0} {1} {2} = {3}",
                    a, operNo, b, mInfo.Invoke(null, new object[] { a, b })));
            }
        }
    }
}

在Main方法中添加如下代码:

Console.WriteLine("调用Operations类内各函数:");
UseOperation("ADD", 3, 5);
UseOperation("MINUS", 9, 4);
UseOperation("MULTIPLY", 3, 7);
UseOperation("DIVIDE", 8, 2);
UseOperation("MOD", 15, 4);

输出结果如下:

224708_pYVr_1425762.png

END

转载于:https://my.oschina.net/Tsybius2014/blog/544292

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值