Какая разница между динамическими (С# 4) и var?

Я прочитал тонну статей о новом ключевом слове, который будет поставляться с С# v4, но я не мог различить "динамический" и "var".

В этой статье я задумался над этим, но я все еще не вижу никакой разницы.

Можно ли использовать "var" только как локальную переменную, но динамическую как локальную, так и глобальную?

Извините за мое незнание, но вы можете показать какой-то код без динамического ключевого слова, а затем показать тот же код с динамическим ключевым словом?

Ответ 1

var является статическим типизированным - компилятор и среда выполнения знают тип - они просто сохраняют вас при наборе текста... следующие на 100% идентичны:

var s = "abc";
Console.WriteLine(s.Length);

и

string s = "abc";
Console.WriteLine(s.Length);

Все, что произошло, заключалось в том, что компилятор понял, что s должен быть строкой (из инициализатора). В обоих случаях он знает (в IL), что s.Length означает свойство (экземпляр) string.Length.

dynamic является очень другим зверем; он наиболее похож на object, но с динамической отправкой:

dynamic s = "abc";
Console.WriteLine(s.Length);

Здесь s набирается как динамическое. Он не знает о string.Length, потому что он не знает ничего о s во время компиляции. Например, следующее будет компилироваться (но не запускаться):

dynamic s = "abc";
Console.WriteLine(s.FlibbleBananaSnowball);

Во время выполнения (только) он будет проверять свойство FlibbleBananaSnowball - не сможет найти его и взорваться в ливне искр.

С помощью dynamic свойства/методы/операторы/etc разрешены во время выполнения на основе фактического объекта. Очень удобно разговаривать с COM (который может иметь только свойства времени исполнения), DLR или другие динамические системы, например javascript.

Ответ 2

Переменные, объявленные с помощью var, неявно, но статически типизированы. Переменные, объявленные с помощью Динамические, динамически типизируются. Эта возможность была добавлена ​​в среду CLR для поддержки динамических языков, таких как Ruby и Python.

Я должен добавить, что это означает, что объявления динамические разрешены во время выполнения, объявления var разрешаются во время компиляции.

Ответ 3

Я собираюсь объяснить разницу между динамическими и var.

dynamic d1;
d1 = 1;
d1 = "http://mycodelogic.com";

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

var v1;  // Compiler will throw error because we have to initialized at the time of declaration  
var v2 = 1; // Compiler will create v1 as **integer**
v2 = "Suneel Gupta"; // Compiler will throw error because, compiler will not recreate the type of variable 


При использовании ключевого слова var тип определяется компилятором во время компиляции, тогда как при использовании ключевого слова dynamic тип определяется временем выполнения.
' var, сильно неявно типизированная локальная переменная, для которой компилятор может определить тип из выражения инициализации - очень полезно при программировании LINQ.
У компилятора нет информации о переменной динамической. поэтому компилятор не будет отображать никакой информации.
У компилятора есть вся информация о сохраненном значении типа var, поэтому компилятор будет отображать интеллект. Тип
dynamic может быть передается как аргумент функции, а функция также может возвращать тип объекта. Но тип var не может передаваться как аргумент функции, а функция не может возвращать тип объекта. Этот тип переменной может работать в области, где он определен.

Ответ 4

var подразумевает, что применяется статическая проверка типа (раннее связывание). dynamic подразумевает, что применяется динамическая проверка типов (поздняя привязка). С точки зрения кода, рассмотрите следующее:

class Junk
{
    public void Hello()
    {
        Console.WriteLine("Hello");
    }
}

class Program
{
    static void Main(String[] args)
    {
        var a = new Junk();
        dynamic b = new Junk();

        a.Hello();

        b.Hello();
    }
}

Если вы скомпилируете это и проверите результаты с помощью ILSpy, вы обнаружите, что компилятор добавил некоторый поздний код привязки, который будет обрабатывать вызов Hello() из b, тогда как, поскольку раннее связывание было применено к a, a для прямого вызова Hello().

например. (Разблокировка ILSpy)

using System;
namespace ConsoleApplication1
{
    internal class Junk
    {
        public void Hello()
        {
            Console.WriteLine("Hello");
        }
    }
}

using Microsoft.CSharp.RuntimeBinder;
using System;
using System.Runtime.CompilerServices;
namespace ConsoleApplication1
{
    internal class Program
    {
        [CompilerGenerated]
        private static class <Main>o__SiteContainer0
        {
            public static CallSite<Action<CallSite, object>> <>p__Site1;
        }
        private static void Main(string[] args)
        {
            Junk a = new Junk();      //NOTE: Compiler converted var to Junk
            object b = new Junk();    //NOTE: Compiler converted dynamic to object
            a.Hello();  //Already Junk so just call the method.

                          //NOTE: Runtime binding (late binding) implementation added by compiler.
            if (Program.<Main>o__SiteContainer0.<>p__Site1 == null)
            {
                Program.<Main>o__SiteContainer0.<>p__Site1 = CallSite<Action<CallSite, object>>.Create(Binder.InvokeMember(CSharpBinderFlags.ResultDiscarded, "Hello", null, typeof(Program), new CSharpArgumentInfo[]
                {
                    CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
                }));
            }
            Program.<Main>o__SiteContainer0.<>p__Site1.Target(Program.<Main>o__SiteContainer0.<>p__Site1, b);
        }
    }
}

Самое лучшее, что вы можете сделать, чтобы обнаружить разницу, - написать себе небольшое консольное приложение, подобное этому, и протестировать его самостоятельно с помощью ILSpy.

Ответ 5

Одно большое различие - вы можете иметь динамический тип возврата.

dynamic Foo(int x)
{
    dynamic result;

    if (x < 5)
      result = x;
    else
      result = x.ToString();

    return result;
}

Ответ 6

Вот простой пример, демонстрирующий разницу между Dynamic (4.0) и Var

dynamic  di = 20;
dynamic ds = "sadlfk";
var vi = 10;
var vsTemp= "sdklf";

Console.WriteLine(di.GetType().ToString());          //Prints System.Int32
Console.WriteLine(ds.GetType().ToString());          //Prints System.String
Console.WriteLine(vi.GetType().ToString());          //Prints System.Int32
Console.WriteLine(vsTemp.GetType().ToString());      //Prints System.String

**ds = 12;**   //ds is treated as string until this stmt now assigning integer.

Console.WriteLine(ds.GetType().ToString());          **//Prints System.Int32**

**vs = 12**; //*Gives compile time error* - Here is the difference between Var and Dynamic. var is compile time bound variable.

Шива Мамиди

Ответ 7

var является просто сокращением для объявления нормального типа, где вы позволяете компилятору угадать правильный тип.

dynamic - новый (статический) тип, где все проверки выполняются во время выполнения, а не компилятором.

Ответ 8

Тип переменной, объявленной с var, определяется компилятором, это ярлык для указания имени типа, не более того.

Однако динамика определяется во время выполнения, компилятор не имеет представления о фактическом типе, и все обращения к методу/полю/свойства с этой переменной будут разработаны во время выполнения.

Ответ 9

Это - хорошее видео с YouTube, которое рассказывает о var VS Dynamic с практической демонстрацией.

Ниже приведено более подробное описание моментального снимка.

Var раннее связывание (статически проверено), в то время как динамическое опоздание связывается (динамически оценивается).

Ключевое слово

Var смотрит на ваши данные с правой стороны, а затем во время компиляции решает левый тип данных. Другими словами, ключевое слово var просто сохраняет вас, набирая много вещей. Посмотрите на изображение ниже, где, когда мы предоставили строковые данные, и переменная x отображает строковый тип данных в моем подсказке.

enter image description here

С другой стороны, динамическое ключевое слово для совершенно разных целей. Динамические объекты оцениваются во время выполнения. Например, в приведенном ниже коде свойство "Длина" существует или не оценивается во время выполнения. Я специально набрал небольшой "l", поэтому эта программа скомпилирована в порядке, но когда она фактически выполняется, она выкинула ошибку, когда свойство "длина" (SMALL "l" ).

enter image description here

Ответ 10

динамическая переменная и переменная var могут хранить любой тип значения, но необходимо инициализировать "var" во время объявления.

У компилятора нет никакой информации о переменной типа "dynamic". var is compiler safe i.e компилятор имеет всю информацию о сохраненном значении, так что он не вызывает никаких проблем во время выполнения.

Динамический тип может быть передан как аргумент функции, и функция также может вернуть его. Тип Var не может быть передан как аргумент функции, и функция не может вернуть тип объекта. Этот тип переменной может работать в области, где он определен.

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

dynamic: полезно при кодировании с использованием отражения или поддержки динамического языка или с COM-объектами, потому что нам требуется написать меньше кода.

var: полезно при получении результата из запросов linq. В структуре 3.5 он предусматривает поддержку функции linq.

Ссылка: Counsellingbyabhi

Ответ 11

  • Var и динамический тип определения.
  • var во время компиляции, а динамические - во время выполнения.
  • в объявлении var и инициализации оба являются обязательными, как постоянная переменная, а
  • в динамической инициализации может быть во время выполнения, например переменные readonly.
  • в var type любой тип определяется в то время, когда инициализация не может изменить следующую, но
  • dynamic может использовать любой тип, даже пользовательский тип данных.

Ответ 12

Не путайте динамические и var. Объявление локальной переменной с помощью var является просто синтаксическим ярлыком, в котором компилятор выводит конкретный тип данных из выражения. Ключевое слово var может использоваться только для объявления локальных переменных внутри метода, в то время как ключевое слово dynamic может использоваться для локальных переменных, полей и аргументов. Вы не можете использовать выражение для var, но вы можете применить выражение к динамическому. Вы должны явно инициализировать переменную, объявленную с помощью var, в то время как вам не нужно инициализировать переменную, объявленную динамическим.

Ответ 13

  • Ключевое слово Var (неявная типизированная локальная переменная) используется для определения локальных переменных. В случае Var базовый тип данных определяется во время компиляции на основе первоначального присвоения. Когда начальное назначение было выполнено с использованием типа Var, то он станет сильно типизированным. Если вы попытаетесь сохранить какое-либо несовместимое значение с типом Var, это приведет к ошибке времени компиляции.

Пример:

Var strNameList=new List<string>(); By using this statement we can store list of names in the string format. 
strNameList.add("Senthil");
strNameList.add("Vignesh");

strNameList.add(45); // This statement will cause the compile time error.

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

Пример:

dynamic test="Senthil";
Console.Writeline(test.GetType())  // System.String

test=1222;
Console.Writeline(test.GetType())  // System.Int32

test=new List<string>();
Console.Writeline(test.GetType())  //System.Collections.Generic.List'1[System.String]

Он также не поддерживает поддержку IntelliSense. Он не дает лучшей поддержки, когда мы предоставляем работу с linq также. Поскольку он не поддерживает лямбда-выражения, методы расширения и анонимные методы.

Ответ 14

Вот отличия

  • var статически типизирован (время компиляции), динамическое динамическое типирование (время выполнения)

  • Переменная, объявленная как var, может использоваться только локально, динамически переменные могут быть переданы в качестве параметров функции (сигнатура функции может определять параметр как динамический, но не var).

  • с динамическим разрешением свойств происходит во время выполнения и это не тот случай с var, который означает во время компиляции любую переменную объявленный как динамический, может вызывать метод, который может или не может существовать и поэтому компилятор не выдаст ошибку.

  • Тип casting с var невозможен, но с динамическим его возможным (вы можете использовать объект как динамический, но не как var).

Арун Виджайрагаван