2009-10-18 2 views
35

Не могли бы вы объяснить разницу между explicit и implicit типами бросков?В чем разница между явным и неявным типом приведения?

+2

посмотреть на http://msdn.microsoft.com/en-us/library/ms173105 .aspx –

+1

Too .. много .. гуру .. ответили/прокомментирован .. это .. вопрос .. Must .. оставить .. быстро. –

ответ

45

Это немного сложнее, так как «слепок» синтаксис в C# на самом деле делает выбор различных вещей (литой, примитивными преобразовывают, сделанные на заказ преобразовывает и т.д.)

В неявном гипсе, существует очевидный ссылка сохраняющих преобразование между двумя:

List<int> l = new List<int>(); 
IList<int> il = l; 

компилятор может доказать, что это безопасно только от статического анализа (List<int> всегда является IList<int>)

С помощью явного приведения, либо вы говорите компилятору, что вы знаете больше, чем это делает - «Пожалуйста, поверьте мне, но все равно проверьте»:

List<int> l = new List<int>(); 
IList<int> il = l; 
List<int> l2 = (List<int>)il; 

Хотя этот бросок возможно, компилятор вона Не соглашайтесь с тем, что всеIList<int> s на самом деле List<int> - так что мы должны сказать, чтобы это разрешалось.


В неявном примитивного преобразования (providedby язык спецификации), то, как правило, предполагается, что существует безопасный, не рискованный, не с потерями (предостережение: см комментарий Джона) преобразование:

int i = 1; 
float f = i; 

С явным примитивным преобразованием, вполне вероятно, что преобразование может потерять данные, или неочевидный:

float f = 1; 
int i = (int)f; 

С помощью специальных операторов все ставки отключены, и вам придется посмотреть документацию. Это может быть ссылка, или это может быть что угодно. Он может следовать тем же правилам для примитивных преобразований (например: decimal), или это может сделать что-нибудь случайно:

XNamespace ns = "http://abc/def"; // implicit 
XAttribute attrib = GetAttrib(); 
int i = (int)attrib; // explicit (extracts text from attrib value and 
        // parses to an int) 

Оба эти запуска пользовательского кода, с учетом конкретного контекста.

+0

Я думаю, что «без потерь» - очень небольшое завышение. В случае удвоения вы можете * потерять информацию. Спектр говорит о потере точности, но не величине, которая звучит как коп-аут для меня. –

+1

Спецификация, как я ее выяснил - 6.1.2: «Конверсии из int, uint, long или ulong для плавания и от длинного или улунгового до двойного могут привести к потере точности, но никогда не приведут к потере Другие неявные числовые преобразования никогда не теряют никакой информации ». –

+2

Добавлена ​​оговорка к тексту; веселит. –

8
int i = 2; 

float a = i;  // Implicit 
float b = (float)i; // Explicit 
2

Я думаю, что это post объясняет это лучше всего.

2

Явные роли:

int x = 0; 
float y = 3.8f; 

x += (int) y; //Explicit cast. 

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

неявные роли:

int x = 0; 
float y = 3.8f; 

x += y; //Implicit cast 

Компилятор будет жаловаться, потому что дробная часть будет потеряна при преобразовании с плавающей точкой в ​​междунар.

15

В чем разница между Президентом Соединенных Штатов и Президентом Канады?

Поскольку президента Канады нет, трудно ответить на вопрос. Правильная вещь - отойти назад и попросить разъяснить вопрос. «Президент Канады» спрашивает ли королева (церемониальный глава государства), генерал-губернатора (который может налагать вето на счета) или премьер-министра (который фактически выступает в качестве исполнительной власти) или что-то еще? Трудно сказать без разъяснений.

И даже с разъяснением, это неопределенный вопрос. О каких различиях вы хотите знать?

Поскольку в C# нет такой вещи, как «неявный литой», сложно ответить на ваш вопрос. В C# кастинг - это оператор. Поэтому я буду настаивать на этом.

Вы хотели спросить: «В чем разница между явным преобразованием и неявным преобразованием?» Или вы хотели спросить о семантике литого оператора? Или разница между оператором литья и операторами преобразования другого типа? Или ситуации, в которых операторы литья могут «неявно» вставляться в ваш код компилятором? (Например, петля foreach и оператор + = могут как неявно вставлять невидимый литой.)

Не могли бы вы пояснить вопрос? Какие две вещи вы просите сравнить и какие различия вас интересуют?

Возможно, вам стоит прочитать главу «Конверсии» спецификации C#. Коэффициенты хороши, что на любой вопрос, который у вас есть о конверсиях, ответили там.

3

Явные Конверсии

Если преобразование не может быть сделано без риска потери информации, то необходимо выполнить явное преобразование.

Например -

class ExplicitConversions 
{ 
    static void Main() 
    { 
     int x; 
     double y = 6358.057; 
     // Cast double to int. 
     x = (int)y; 
     System.Console.WriteLine(x); 
    } 
} 

неявные преобразования

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

Например -

class ImplicitConversions 
{ 
    static void Main() 
    { 
     int x = 6714; 
     double y; 
     // Cast int to double. 
     y = x; 
     System.Console.WriteLine(y); 
    } 
} 
0

Явных из MSDN -

Если операция преобразования может вызвать исключение или потерять информацию, вы должны пометить его явным.Это предотвращает бесшумный компилятор , вызывающий операцию преобразования с возможными непредвиденными последствиями .

неявной из MSDN -

если преобразование гарантированно не приводит к потере данных

Смежные вопросы