C# 这里的编译时类型安全是什么意思?

C# 这里的编译时类型安全是什么意思?,c#,generics,.net-2.0,C#,Generics,.net 2.0,在通过C#v3的泛型CLR一章中,Jeffrey Richter说下面的TypeList有两个优点 编译时类型安全 装箱值类型 超过列表,但编译时类型安全是如何实现的 //A single instance of TypeList could hold different types. using System; using System.Collections.Generic; using System.Text; namespace MyNamespace { namespace

在通过C#v3的泛型CLR一章中,Jeffrey Richter说下面的
TypeList
有两个优点

  • 编译时类型安全
  • 装箱值类型
  • 超过
    列表
    ,但编译时类型安全是如何实现的

    //A single instance of TypeList could hold different types.
    using System;
    using System.Collections.Generic;
    using System.Text;
    namespace MyNamespace 
    {
        namespace Generics
        {
            class Node
            {
                private Node next_;
    
                public Node(Node next) {
                    next_ = next;        
                }
    
                public Node getNext() {
                    return next_;
                }
            }
            internal sealed class TypeList<T> :Node
            {
                T data_;
                public T getData() {
                    return data_;
                }
    
                public TypeList(T data, Node next):base(next) {
                    data_ = data;
                }
    
                public TypeList(T data):this(data,null) {
    
    
                }
                public override String ToString()
                {
                    return data_.ToString() + (base.getNext() != null ? base.getNext().ToString() : string.Empty);
                }
    
              }
            class Dummmy:Object
            {
                public override String ToString() {
                   return "Dummytype".ToString();
    
                }
    
            }
    
            class Program
            {
                static void Main(string[] args)
                {
                    Dummmy dummy = new Dummmy();
                    Node list = new TypeList<int>(12);
                    list = new TypeList<Double>(12.5121, list);
                    list = new TypeList<Dummmy>(dummy, list);
                    Double a = ((TypeList<Double>)list).getData();//Fails at runTime invalid cast exception
                    Console.WriteLine(list.ToString());
                    Console.Write("sds");
                }
            }
        }
    
    }
    

    //TypeList的单个实例可以包含不同的类型。
    使用制度;
    使用System.Collections.Generic;
    使用系统文本;
    名称空间MyNamespace
    {
    命名空间泛型
    {
    类节点
    {
    私有节点下一步;
    公共节点(下一个节点){
    下一个=下一个;
    }
    公共节点getNext(){
    下一步返回;
    }
    }
    内部密封类类型列表:节点
    {
    T数据;
    公共T getData(){
    返回数据;
    }
    公共类型列表(T数据,下一个节点):基础(下一个){
    数据=数据;
    }
    公共类型列表(T数据):此(数据,空){
    }
    公共重写字符串ToString()
    {
    返回数据\.ToString()+(base.getNext()!=null?base.getNext().ToString():string.Empty);
    }
    }
    类dummy:Object
    {
    公共重写字符串ToString(){
    返回“Dummytype.ToString();
    }
    }
    班级计划
    {
    静态void Main(字符串[]参数)
    {
    dummy dummy=新dummy();
    节点列表=新类型列表(12);
    列表=新类型列表(12.5121,列表);
    列表=新类型列表(虚拟,列表);
    双a=((TypeList)list).getData();//在运行时失败无效强制转换异常
    Console.WriteLine(list.ToString());
    控制台。写入(“sds”);
    }
    }
    }
    }
    
    编译类型安全性意味着您将在编译时获得有关无效类型用法的所有错误,但不会在运行时

    例如,以下代码将导致编译时错误:

    TypeList<int> list = new TypeList<int>(1);
    string someString = list.getData(); // compile error here
    
    TypeList<object> list = new TypeList<object>(1);
    string someString = (string)list.getData(); // runtime error here
    
    类型列表=新类型列表(1);
    string someString=list.getData();//此处编译错误
    
    如果您使用
    TypeList
    ,编译时将不会有安全性,因为编译器不会报告错误,您将得到运行时错误:

    TypeList<int> list = new TypeList<int>(1);
    string someString = list.getData(); // compile error here
    
    TypeList<object> list = new TypeList<object>(1);
    string someString = (string)list.getData(); // runtime error here
    
    类型列表=新类型列表(1);
    string someString=(string)list.getData();//此处出现运行时错误
    
    这意味着,由于TypeList是一个泛型类,因此在编译时可以知道所使用的类型,从而避免在运行时转换为实际使用的类型。

    因为TypeList是泛型的。T的实际类型是在编译时定义的,因此对该类型的任何检查都是在编译时完成的。

    本文档详细介绍了泛型以及为实现泛型而进行的权衡

     Double a = ((TypeList<Double>)list).getData();  //Fails at runTime
    
    编译时类型安全在那里工作。但是您应用了一个cast来让它编译。编译器根据他的假设工作:“他知道自己在做什么,他使用了一个cast”并让它通过。当然不会工作,现在它在运行时爆炸


    您可能会争论“但是编译器知道强制转换不能工作,这不是类型安全的全部内容吗?”。不,强制转换非常强大,它可以让你覆盖编译器知道的内容。这个特定的示例不是很好,但是您必须使用cast将基类引用转换为派生类引用。相当普遍。演员的力量使它变得危险。泛型的最大优点是您不需要使用它们。

    优点是泛型不限制值类型,而不是限制值类型。是的,我理解这一部分,但是编译时类型安全是如何实现的,或者作者所说的编译时类型安全性TypeList的单个实例可以包含不同的类型。这就是为什么选择TypeList而不是某些可以保存单个类型的计时。@yesraaj:TypeList的single实例只能保存在编译时指定的类型T的值。请查看我所讨论的代码段中主块中的示例代码。@yesraaj:在您的示例中,不同的TypeList实例保存的类型不同类型。当您试图提取错误类型的值时,会发生异常。list.getData()//编译器错误,因为list没有getDatamethod@yesraaj-您的TypeList确实有一个getData()成员,但不确定您的意思。list是list类型,而不是TypeList类型。@yesraaj-您怎么会这样想?您的代码显示
    list=newtypelist(dummy,list)