Что здесь подразумевается под безопасностью типов во время компиляции? - PullRequest
2 голосов
/ 25 октября 2010

В главе Generics CLR Via C # v3 Джеффри Рихтер говорит ниже TypeList<T> имеет два преимущества

  1. Безопасность во время компиляции
  2. типы значений бокса

более List<Object>, но как достигается безопасность типов во время компиляции?

//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");
            }
        }
    }

}

Ответы [ 5 ]

5 голосов
/ 25 октября 2010

Безопасность типов при компиляции означает, что вы получите все ошибки об использовании недопустимого типа при времени компиляции , но не при времени выполнения .

Например, следующий код вызовет компиляциюошибка времени:

TypeList<int> list = new TypeList<int>(1);
string someString = list.getData(); // compile error here

И если вы используете TypeList<object>, безопасность компиляции не будет гарантирована, потому что компилятор не сообщит об ошибке, и вы получите ошибку времени выполнения:

TypeList<object> list = new TypeList<object>(1);
string someString = (string)list.getData(); // runtime error here
1 голос
/ 25 октября 2010
 Double a = ((TypeList<Double>)list).getData();  //Fails at runTime

Это суть вашего вопроса. Переменная list на самом деле является TypeList<Dummy>. Компилятор знает это и сгенерировал ошибку во время компиляции, когда вы написали

 Double a = list.getData();

Безопасность во время компиляции на работе там. Но вы применили приведение к компиляции. Компилятор работает исходя из предположения: «он знает, что делает, он использовал приведение» и позволяет ему пройти. Конечно, работать не будет, теперь он бомбит во время выполнения.

Вы могли бы возразить, "но компилятор знает , что приведение не может работать, разве это не безопасность типов?" Нет, приведение очень мощное, оно позволяет вам переопределить то, что знает компилятор. Этот конкретный пример не очень хороший, но вы должны использовать приведение для преобразования ссылки на базовый класс, например, в ссылку на производный класс. Довольно часто. Сила броска - это то, что делает его опасным. Большим преимуществом дженериков является то, что вам не нужно их использовать.

1 голос
/ 25 октября 2010

Поскольку TypeList является универсальным. Фактический тип T определяется во время компиляции, поэтому любая проверка с типом выполняется во время компиляции.

1 голос
/ 25 октября 2010

Это означает, что, поскольку TypeList является универсальным классом, во время компиляции известно, какой тип используется, что избавляет вас от необходимости приводить во время выполнения к фактическому используемому типу.

0 голосов
/ 25 октября 2010

Этот документ, Разработка и внедрение обобщений для .NET Common Language Runtime , подробно описывает дженерики и компромиссы, которые были сделаны для их реализации.

...