泛型编程之强制类型转换、继承和泛型

泛型和强制类型转换

    隐式强制转换

        C#编译器只允许将泛型参数隐式强制转换object泛型参数的约束指定的类型,代码如下

interface IMyInterface
    {
        //
    }
    class MyClass
    {
        //
    }
    class ConvertOfTypeDemo<T> where T : MyClass, IMyInterface
    {
        void MyMethod(T t)
        {
            IMyInterface obj1 = t;
            MyClass obj2 = t;
            Object obj3 = t;
        }
    }


显式强制转换

        C#编译器允许你将泛型参数显式强制转换到其他任何接口,但不能转换到类,代码如下

interface IMyInterface
    {
        //
    }
    class MyClass
    {
        //
    }
    class ConvertOfTypeDemo<T>
    {
        void MyMethod(T t)
        {
            IMyInterface obj1 = (IMyInterface)t;
 
            MyClass obj2 = (MyClass)t;//无法将类型“T”转换为“Demo3.MyClass”
 
        }
    }


        在这里我们可以采取一种措施来避免编译时出现上述错误,由于泛型参数可以隐式转换object类型,那么我们在这里可以定义一个临时变量来解决此事,代码如下


interface IMyInterface
    {
        //
    }
    class MyClass
    {
        //
    }
    class ConvertOfTypeDemo<T>
    {
        void MyMethod(T t)
        {
            IMyInterface obj1 = (IMyInterface)t;
 
            object tmp = t;
            MyClass obj2 = (MyClass)tmp;
 
        }
    }


        但是在上面的代码中,会又有可能出现值类型参数的装箱与拆箱以及类型安全得不到保证,这就违反了我们使用泛型参数的初衷,虽然上述代码可以在编译时通过,但是在运行时有可能会报错,所以也不推荐使用。

        不用说强制类型转换的危险性大家都知道,如果泛型参数的实参不是派生自您要显式强制转换到的类型,则有可能报错,为了解决这个问题,我们一般采用is和as操作符。代码如下

interface IMyInterface
    {
        //
    }
    class MyClass
    {
        //
    }
    class ConvertOfTypeDemo<T>
    {
        void MyMethod(T t)
        {
            if (t is int)
            {
                //
            }
 
            if (t is MyClass)
            {
                //
            }
 
            if (t is IMyInterface)
            {
                //
            }
 
            string str0 = t as string;
            if (str0 != null)
            {
                //
            }
 
            IMyInterface m = t as IMyInterface;
            if (m != null)
            {
                //
            }
 
            MyClass my = t as MyClass;
            if (my != null)
            {
                //
            }
 
        }
    }


继承和泛型

    若子类不是泛型类,那在泛型基类派生时,基类必须提供类型实参,而不是泛型参数,如下

    public class MyBaseClass<T>
    {
 
    }
    public class SubClass1 : MyBaseClass<int>
    {
 
    }
    //错误 找不到类型或命名空间名称“T”
    public class SubClass2 : MyBaseClass<T>
    {
 
    }


    若子类是泛型类,而非具体的类型实参,则可以使用子类的泛型参数作为基类泛型参数指定的类型


    public class MyBaseClass<T>
    {
 
    }
 
    //MyBaseClass类中的泛型参数(非类型实参)必须同SubClass1中相同,基类泛型参数为类型实参的除外
    public class SubClass1<K> : MyBaseClass<K>
    {
 
    }
 
    //可以编译通过,原因是如果基类指定了类型实参,就相当于泛型继承自一个非泛型类
    public class SubClass3<K> : MyBaseClass<int>
    {
        
    }
 
    //错误 找不到类型或命名空间名称“T”
    public class SubClass2<K> : MyBaseClass<T>
    {
 
    }


        在使用子类泛型参数时,必须在子类级别再重复在基类级别规定的任何约束,如下


    public class MyBaseClass<T> where T:new()
    {
 
    }
 
    public class MySubClass<T> : MyBaseClass<T> where T : new()
    {
 
    }
 
    /********************************************************************
    错误     “T”必须是具有公共的无参数构造函数的非抽象类型,
     * 才能用作泛型类型或方法“Demo3.MyBaseClass<T>”中的参数“T”    
    *********************************************************************/
    public class MySubClass1<T> : MyBaseClass<T>
    {
 
    }


        虚方法的继承

        若子类不是泛型类,虚方法重写代码如下

    public class MyBaseClass<T>
    {
        public virtual T SomeMethod()
        {
 
        }
    }
    public class MySubClass : MyBaseClass<int>
    {
        public override int SomeMethod()
        {
        }
    }


        若子类是泛型类,基类也是泛型类的虚方法重写,代码如下


    public class MyBaseClass<T>
    {
        public virtual T SomeMethod()
        {
 
        }
    }
    public class MySubClass<T> : MyBaseClass<T>
    {
        public override T SomeMethod()
        {
        }
    }


    泛型抽象类、泛型抽象方法和泛型接口的使用


    public interface ISomeInterface<T>
    {
        T SomeMethod(T t);
    }
    public abstract class MyBaseClass<T>
    {
        public abstract T SomeMethod(T t);
    }
    public class MySubClass<T> : MyBaseClass<T>
    {
        public override T SomeMethod(T t)
        {
        }
    }


    泛型类型中泛型参数的运算符的实现

    由于在运行时不能确定泛型参数的实参类型,所以不能直接对泛型参数进行加、减、乘和除等运算操作。但是我们可以通过定义泛型操作,使用抽象方法(最好使用接口)进行补偿,由于抽象方法的内部不能有任何代码,因此可以在基类级别指定泛型操作,并且在子类级别提供具体的类型和实现。

    用抽象类和抽象方法实现运算符操作,代码如下

    public abstract class BaseCalculator<T>
    {
        public abstract T Add(T arg1, T arg2);
        public abstract T Subtract(T arg1, T arg2);
        public abstract T Mutiple(T arg1, T arg2);
        public abstract T Divide(T arg1, T arg2);
    }
 
    public class SubCalculator : BaseCalculator<int>
    {
        public override int Add(int arg1, int arg2)
        {
            return arg1 + arg2;
        }
 
        public override int Subtract(int arg1, int arg2)
        {
            return arg1 - arg2;
        }
 
        public override int Mutiple(int arg1, int arg2)
        {
            return arg1 * arg2;
        }
 
        public override int Divide(int arg1, int arg2)
        {
            return arg1 / arg2;
        }
    }


    用接口实现泛型参数四则运算操作


    public interface IBaseCalculator<T>
    {
        T Add(T arg1, T arg2);
        T Subtract(T arg1, T arg2);
        T Mutiple(T arg1, T arg2);
        T Divide(T arg1, T arg2);
    }
 
    public class SubCalculator : IBaseCalculator<int>
    {
        public int Add(int arg1, int arg2)
        {
            return arg1 + arg2;
        }
 
        public int Subtract(int arg1, int arg2)
        {
            return arg1 - arg2;
        }
 
        public int Mutiple(int arg1, int arg2)
        {
            return arg1 * arg2;
        }
 
        public int Divide(int arg1, int arg2)
        {
            return arg1 / arg2;
        }
    }


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年3月    »
123
45678910
11121314151617
18192021222324
25262728293031
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864