Dinamik (C # 4) ve var arasındaki fark nedir?


199

C # v4 ile gönderim yapan yeni anahtar kelime hakkında bir sürü makale okumuştum, ancak "dinamik" ve "var" arasındaki farkı bulamadım.

Bu makale beni düşündürdü, ama hala bir fark göremiyorum.

"Var" ı yalnızca yerel bir değişken olarak kullanabileceğiniz gibi, hem yerel hem de global olarak dinamik olarak kullanabiliyor musunuz?

Dinamik anahtar kelime olmadan bir kod gösterebilir ve ardından dinamik anahtar kelime ile aynı kodu gösterebilir misiniz?

Yanıtlar:


455

varstatik yazılır - derleyici ve çalışma zamanı türü bilir - sadece bazı yazarak kaydederler ... aşağıdakiler% 100 aynıdır:

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

ve

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

Oldu ki tüm olmasıydı derleyici anladım s(başlatıcısı itibaren) bir dize olmalıdır. Her iki durumda da (IL'de) bunun s.Length(örnek) string.Lengthözelliği anlamına geldiğini bilir .

dynamica, çok farklı bir hayvan; en çok benzeyen object, ancak dinamik gönderimle:

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

Burada dinamik olaraks yazılır . Yaklaşık bilmez o bilmediği için, herhangi bir şey hakkında derleme zamanında. Örneğin, aşağıdakiler de derlenir (ancak çalıştırılmaz):string.Lengths

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

Çalışma zamanında (yalnızca), özelliği kontrol eder FlibbleBananaSnowball- bulamaz ve kıvılcım duşunda patlayabilir.

İle dynamic, özellikler / yöntemler / işleçler / vb . Çalışma zamanında gerçek nesneye göre çözümlenir . COM (yalnızca çalışma zamanı özelliklerine sahip olabilen), DLR veya diğer dinamik sistemlerle konuşmak için çok kullanışlıdır javascript.


3
İlginç bir soru, statik olarak beyan edilen sınıfların dinamik ataları olup olmadığıdır. Örnek: sınıf X {public int Y {get; set;}} dynamic (X) s = GetSpecialX (); Arama dizesi testi = sY; derleyici Y'yi bildiğinden bir derleyici hatası oluşturur, ancak test2 = sZ dizesi iyi derlenir ve çalışma zamanında denetlenir. Böyle yarı dinamik sınıfların çok değerli olduğunu düşünebilirdim!
mmmmmmmm

@rstevens - IIRC, bir arabirim aracılığıyla dinamik davranış ekleyebilirsiniz (C # dinamik türlerini uygulamak için doğrudan dil desteği olmamasına rağmen - sadece onları tüketmek), bu yüzden bu gerçekçi değil ... oh eğlenebiliriz; - p
Marc Gravell

Her ne kadar bazen varalt türler ve örtülü dökümler nedeniyle istenmeyebilecek türleri çıkarabileceğine dikkat etmek önemlidir . Yani, örtülü dökümler meydana vargeldiğinde beklenenden statik olarak farklı bir türü çözmüş olabilir (en önemlisi daha genel bir türdür, ancak bununla sınırlı değildir). Önemsiz bir örnektir vs vs , ancak diğer daha sinsi (ve gerçekçi) vakaları oluşabilir ve ince hatalara yol açabilir. object x = ""var x = ""var x = "" as object

Marc'ın iyi örneğini daha ayrıntılı olarak ele almak için, ilk durumda (statik tipte), derleyici tam olarak hangi aşırı yüklenmeleriWriteLine aradığını bilir . Bu "bağlayıcı" derleme zamanı olur. Durumunda, dynamictürünün .Lengthde olması gerekir dynamicve çalışma zamanına kadar hangi aşırı yükün (varsa) WriteLineen uygun olduğuna karar verilmez . Bağlama çalışma zamanı olur.
Jeppe Stig Nielsen

4
varAnahtar sözcüğü Visual Studio'da üzerine getirdiğinizde , çıkarım yapılan gerçek tür görüntülenir. Türün derleme zamanında bilindiğini gösterir.
Christian Fredh

56

Var ile bildirilen değişkenler dolaylı olarak ancak statik olarak yazılır. Dinamik ile bildirilen değişkenler dinamik olarak yazılır. Bu özellik Ruby ve Python gibi dinamik dilleri desteklemek için CLR'ye eklendi.

Bunun dinamik bildirimlerin çalışma zamanında çözüldüğü , değişken bildirimlerin derleme zamanında çözüldüğü anlamına geldiğini de eklemeliyim .


42

Dinamik ve var arasındaki farkı açıklayacağım .

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

Bu çalışacak. derleyici dinamik değişken türünü yeniden oluşturabilir .
İlk o kadar tipini yaratmak tamsayı ve bu derleyici sonra mümkün türünü baştan yaratacak dize
ancak durumunda 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 ' anahtar sözcüğünü kullanırken, tür derleyici tarafından derleme zamanında belirlenirken, ' dinamik ' anahtar sözcüğü kullanılırken, tür çalışma zamanı tarafından belirlenir.
' var ' anahtar kelimesi, derleyicinin başlatma ifadesinden türü belirleyebildiği, açıkça örtülü olarak yazılan bir yerel değişken - LINQ programlama yaparken çok kullanışlıdır.
Derleyicinin dinamik değişken türü hakkında hiçbir bilgisi yoktur . böylece derleyici herhangi bir zeka göstermeyecektir.
derleyici var türünün saklanan değeri hakkında tüm bilgilere sahiptir, böylece derleyici istihbarat gösterir.
dinamik tür işlev bağımsız değişkeni olarak geçebilir ve işlev de nesne türünü döndürebilir.
Ancak
var türü işlev bağımsız değişkeni olarak geçemez ve işlev nesne türünü döndüremez. Bu tür bir değişken, tanımlandığı kapsamda çalışabilir.


14

var, statik tip denetiminin (erken bağlama) uygulandığını gösterir. dinamik, dinamik tür denetiminin (geç bağlama) uygulandığını gösterir. Kod açısından aşağıdakileri göz önünde bulundurun:

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();
    }
}

Bunu derlerseniz ve sonuçları ILSpy ile incelerseniz, derleyicinin b'den Hello () çağrısını işleyecek bazı geç bağlama kodu eklediğini görürsünüz. () direkt olarak.

ör. (ILSpy sökme)

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

Farkı keşfetmek için yapabileceğiniz en iyi şey, kendinize böyle bir konsol uygulaması yazmak ve ILSpy ile kendiniz test etmektir.


IL'nin derlemeden sonra her ikisine de nasıl davrandığına dair büyük temel örnek. Teşekkürler.
Kings

12

Büyük bir fark - dinamik bir dönüş tipine sahip olabilirsiniz.

dynamic Foo(int x)
{
    dynamic result;

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

    return result;
}

10

Dinamik (4.0) ve Var arasındaki farkı gösteren basit bir örnek

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.

Shiva Mamidi


2
Benim izlenimim, **kod örneğindeki karakterlerin varlığının sadece vurguyu göstermesi ve gerçek çalışma kodunun bir parçası olmamasıdır.
DavidRR

7

var derleyicinin doğru türü tahmin etmesine izin verdiğiniz normal bir tür bildirimi için bir kısayol.

dynamic derleyici tarafından değil, tüm kontrollerin çalışma zamanında yapıldığı yeni (statik) bir türdür.


4

Var ile bildirilen bir değişkenin türü derleyici tarafından belirlenir, türün adını belirtmek için bir kısayoldur, başka bir şey değildir.

Ancak dinamik çalışma zamanında belirlenir, derleyicinin gerçek tür hakkında hiçbir fikri yoktur ve bu değişkenle tüm yöntem / alan / özellik erişimleri çalışma zamanında çalışacaktır.


3

Bu pratik gösteri ile varVS hakkında konuşan güzel bir youtube video Dynamic.

Aşağıda anlık görüntü ile daha ayrıntılı bir açıklama bulunmaktadır.

Varlık erken bağlanır (statik olarak kontrol edilir), dinamik ise geç bağlanır (dinamik olarak değerlendirilir).

Var anahtar kelime sağ taraftaki verilerinize bakar ve daha sonra derleme zamanı sırasında sol taraftaki veri türüne karar verir. Dize verisi verdiğimizde ve x değişkeni, araç ipucumda dize veri türünü gösterdiğinde aşağıdaki resme bakın.

resim açıklamasını buraya girin

Diğer yandan, dinamik anahtar kelime tamamen farklı bir amaç içindir. Dinamik nesneler çalışma sırasında değerlendirilir. Örneğin aşağıdaki kodda "Uzunluk" özelliği var veya değil çalışma sırasında değerlendirilir. Ben bilerek küçük bir "l" yazdım, bu nedenle bu program iyi derlenmiş ama aslında çalıştırıldığında "length" özelliği bir hata attı denir (KÜÇÜK "l").

resim açıklamasını buraya girin


2

dinamik değişken ve var değişkeninin her ikisi de her türlü değeri depolayabilir, ancak bildirim sırasında 'var' değerini başlatmak gerekir.

Derleyicinin 'dinamik' değişken türü hakkında hiçbir bilgisi yoktur. var derleyici güvenlidir, yani derleyici saklanan değer hakkında tüm bilgilere sahiptir, böylece çalışma zamanında herhangi bir soruna neden olmaz.

Dinamik tür işlev bağımsız değişkeni olarak geçirilebilir ve işlev de geri döndürebilir. Var türü işlev bağımsız değişkeni olarak iletilemez ve işlev nesne türünü döndüremez. Bu tür bir değişken, tanımlandığı kapsamda çalışabilir.

Dinamik Döküm gerekli değilse, ancak depolanmış tiple ilgili özellikleri ve yöntemleri bilmeniz gerekirken, var için Döküm gerekmez çünkü derleyici işlemi gerçekleştirmek için tüm bilgilere sahiptir.

dynamic: Daha az miktarda kod yazmamız gerektiğinden, yansıma veya dinamik dil desteği veya COM nesneleriyle kodlama yaparken kullanışlıdır.

var: Linq sorgularından sonuç alırken kullanışlıdır. 3.5 çerçevesinde linq özelliğini desteklemek için tanıtıldı.

Kaynak: Counsellingbyabhi


2
  1. Değişken ve dinamik tanımlama tipi.
  2. dinamik çalışma zamanında iken derleme zamanında var.
  3. var bildiriminde ve ilklendirmede sabit değişken gibi her ikisi de zorunludur.
  4. dinamik başlatma sırasında, salt okunur değişkenler gibi çalışma zamanında olabilir.
  5. var tipinde hangi tipte karar verilirse o zaman başlatma bir sonraki değişemez
  6. dinamik kullanıcı türü bile veri tanımlamak herhangi bir tür kabul edebilir.

1

Dinamik ve değişkenleri karıştırmayın. Var kullanarak yerel bir değişken bildirmek, derleyicinin belirli veri türünü bir ifadeden çıkarmasını sağlayan sözdizimsel bir kısayoldur. Var anahtar sözcüğü yalnızca bir yöntem içindeki yerel değişkenleri bildirmek için kullanılabilirken, dinamik anahtar sözcük yerel değişkenler, alanlar ve bağımsız değişkenler için kullanılabilir. Bir ifadeyi var değerine atayamazsınız, ancak bir ifadeyi dinamiğe atayabilirsiniz. Dinamik ile bildirilen bir değişkeni başlatmanıza gerek yokken, var kullanarak bildirilen bir değişkeni açıkça başlatmalısınız.


1
  1. Yerel değişkenleri tanımlamak için Var (Örtük yazılan yerel değişken) anahtar sözcüğü kullanılır.Var durumunda, temel atama türü, ilk atamaya dayalı olarak derleme zamanında belirlenir. İlk atama Var türüyle yapıldıktan sonra, Var türüyle uyumsuz bir değer depolamaya çalışırsanız, derleme zamanı hatasına neden olur.

Misal:

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.

Ancak Dinamik türde, temel alınan tür yalnızca çalışma zamanında belirlenir.Dinamik veri türü derleme zamanında denetlenmez ve ayrıca güçlü bir şekilde yazılmaz. Dinamik tür için herhangi bir başlangıç ​​değeri atayabilir ve daha sonra herhangi bir yeni öğeye yeniden atanabilir yaşam süresi boyunca değer.

Misal:

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 desteği de sağlamaz. Linq ile çalıştığımızda daha iyi destek vermez çünkü lambda ifadelerini, uzantı yöntemlerini ve anonim yöntemleri desteklemez.


1

İşte farklılıklar

  • var statik olarak yazılır (derleme zamanı), dinamik dinamik olarak yazılır (çalışma süresi)

  • Var olarak bildirilen bir değişken yalnızca yerel olarak kullanılabilir, dinamik değişkenler işleve parametreler olarak aktarılabilir (işlev imzası bir parametreyi dinamik olarak tanımlayabilir ancak var değil).

  • dinamik ile özelliklerin çözünürlüğü çalışma zamanında olur ve bu durum böyle değildir.

  • Değişken ile var yazmak mümkün değil, ancak dinamik ile mümkündür (bir nesneyi dinamik olarak var, ancak var olarak değil).

Arun Vijayraghavan

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.