泛型如何进行隐式转换

来源:互联网 发布:阿里云 vs aws 编辑:程序博客网 时间:2024/06/06 21:02

在对象之间,我们通过多态进行创建对象,父类编译,子类运行,从而达到代码上的复用性与解耦性。但我们发现在泛型中List<>限制的类型,我们不能类似的通过多态来进行编译运行:List<BaseA> list = new List<SubA>();发现会出现如下错误


1.为什么使用此方式

2.该如何解决

3.为什么出现这种现象

以目前我遇到的情况来说,避免了方法的重载,且方法实现方式却是一样的,如果不能通过上述形式,那么我们将必须使用方法的重载,仅因为传递参数类型不同,而写入过多的相同代码。

如下面代码形式:

    class Program
    {
        static void Main(string[] args)
        {

    //定义父类对象
            BaseA baseA;
            SubA subA = new SubA();

    //父类获得方法返回值,参数为子类对象
            baseA = TestObject(subA);
            SubB subB = new SubB();

    //避免了方法的重载
            baseA = TestObject(subB);

    //我们在泛型中希望像多态一般实现避免方法的重载,但事实上它出现了以下显示的错误

            List<SubA> subAList = new List<SubA>();
            TestList(subAList);//错误点


            Console.ReadKey();           
        }
        private static List<BaseA> TestList(List<BaseA> list)
        {
            List<BaseA> listBase = new List<BaseA>();
            for (int i = 0; i < list.Count; i++)
            {
                listBase.Add(list[i]);
            }
            return listBase;
        }
        private static BaseA TestObject(BaseA baseA)
        {
            return baseA;
        }
    }
    class BaseA { }
    class SubA :BaseA{ }
    class SubB : BaseA { }

为什么使用此方式?

所以我希望如多态一般,开放参数接口的范围,达到代码的复用性质。

我们希望在方法中接收的参数能够是一个通用的参数,在调用该方法时,无论你传递什么参数进来,都是能够运行我这个方法的。如在传递对象来时,我们在方法定义参数类型是父类型,在调用该方法时,将子类型传递给它,方法依然能够正常运行。所以我们希望,在传递泛型时,也能够利用向上转型机制,达到我们想要的目的。

在解决问题中,我们也可以将参数采用object作为替代,但毫无疑问,我们将面临装箱与拆箱之间的性能损失。而若是使用泛型,在哪个对象调用该方法时,把已知的对象告诉它,让它的对象也做出相应的改变,便是我们想要避免的问题能够得到解决。

如何解决问题?

在java中,可以发现,可以使用通配符或者声明为T类型来操作完成。


可以发现,在调用方法TestList时候,我们可以传递任何对象进来,且不需要是否拥有继承关系,因为在声明泛型时,只能等价声明,不能隐式作为转换。

我们希望C#也可以类似地声明。我们发现C#也能以类似的方式达到此效果。

泛型类:

public class ListClass<T>
    {
        public static void GetList(List<T> list)
        {


        }
    }

方法上的泛型

        private static void GetList<T>(List<T> list)
        {


        }

结果上来看,我们达到了一致效果。

为什么出现这种现象?

在过程中最让我疑惑的便是,在泛型容器里设置的类型为什么不能像单个的对象一般,具有多态关系。在看java的过程中,也逐一解惑了,在使用中只能对其容器进行判别,而容器内部的属性是未知的。

以上纯属个人观念想法,泛型还有很多不懂的地方,希望能帮忙修正出来,谢谢。

原创粉丝点击