C# 利用【反射】+【接口】,对【泛型】来点特别的【约束】

目录

场景简介

运用示例

Ⅰ 使用【接口】 约束 T ,令它只能是若干 Box 中的一种 Box

Ⅱ 使用【反射】,令GetBox 中仍然可以使用 T 的构造函数并返回 T 类型的实例对象


场景简介

  这是你自定义的KeySelectBox类型

public class KeySelectBox
{
    public KeySelectBox()
    {

    }
}

  这是你自定义的BoxObject类型

public class BoxObject
{
   public static T GetBox<T>()
   {
       
   }
}

BoxObject表示对所有Box的统筹,你可以定义KeySelectBox、TextBox……这样的Box。

接着,统一调用泛型函数GetBox<T>来获取指定类型的Box.

运用示例

Ⅰ 使用【接口】 约束 T ,令它只能是若干 Box 中的一种 Box

(1)添加一个名为 Box 的【接口】

    public interface Box
    {

    }

(2)所有自定义的 Box 都去实现这个【接口】,这里以KeySelectBox为例

    public class KeySelectBox : Box
    {
        public KeySelectBox() { }
    }

(3)用【接口】来约束泛型函数 GetBox<T>

        public static T GetBox<T>() where T : Box
        {

        }

  如此一来,GetBox<T> 的 T 就只能填入指定的自定义类型了!

Ⅱ 使用【反射】,令GetBox<T> 中仍然可以使用 T 的构造函数并返回 T 类型的实例对象

这个在开发类库的时候有用,因为有些类型是你不希望能在类库外被直接实例化的,你希望通过某个泛型函数来统一这些类型的调度,你可能会把它们的构造函数设置为 【internal】 的,但这么做的话,你将无法使用 【where T : new()】因为new()约束要求 【public、无参】 构造函数,自然,你也无法执行下述操作:

T target = new T();

这个时候就该【反射】排上用场啦!

        public static T GetBox<T>() where T : Box
        {
            ConstructorInfo? constructor = typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[0], null);
            //反射 T 的无参构造函数信息

            if (constructor == null) { throw new InvalidOperationException($"您尝试获取的{typeof(T).Name}组件不存在构造函数!"); }
            //若未能反射到无参构造函数,则抛出异常

            T result = (T)constructor.Invoke(null);
            //获取成功,则调用 T 的构造函数

            return result;
        }

至此,你的类库将只允许使用者通过统一的泛型函数 GetBox<T> 来获取你在类库中定义类型的实例对象。

当然,你也许注意到了,这里的【接口】是【public】,这意味着,使用这个类库的人,一样可以定义自己的 Box ,只需实现 【Box接口】,就能同样使用 GetBox<T> 了。

个人认为,这种设计能使类型的管理更清晰,使用过程更安全,也具备不错的可拓展性!

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值