C # 4.0'daki 'dinamik' tip ne için kullanılır?


236

C # 4.0, 'dinamik' adlı yeni bir tür tanıttı. Her şey kulağa hoş geliyor, ama bir programcı bunu ne için kullanır?

Günü kurtarabilecek bir durum var mı?



COM veya dinamik olarak yazılmış dillerle çalışırken kullanışlıdır. Örneğin, dilinizi kodlamak için lua veya python kullanırsanız, komut dosyası kodunu normal kodmuş gibi çağırmanız çok uygundur.
CodesInChaos


Umarım bu makale sorunuzun tam cevabına sahiptir visualstudiomagazine.com/Articles/2011/02/01/…
Geliştirici

Yanıtlar:


196

Dinamik anahtar kelime C # 4.0 için yenidir ve derleyiciye bir değişkenin türünün değişebileceğini veya çalışma zamanına kadar bilinmediğini söylemek için kullanılır. Bir Nesne ile onu dökmek zorunda kalmadan etkileşime girebileceğini düşünün.

dynamic cust = GetCustomer();
cust.FirstName = "foo"; // works as expected
cust.Process(); // works as expected
cust.MissingMethod(); // No method found!

Tür Müşteri olarak döküm yapmamıza veya müşteri ilan etmemize gerek olmadığına dikkat edin. Dinamik olarak bildirdiğimiz için çalışma zamanı devralır ve FirstName özelliğini arar ve ayarlar. Elbette, dinamik bir değişken kullanırken derleyici türü denetiminden vazgeçiyorsunuz. Bu, cust.MissingMethod () çağrısının derleneceği ve çalışma zamanına kadar başarısız olmadığı anlamına gelir. MissingMethod Customer sınıfında tanımlanmadığından, bu işlemin sonucu bir RuntimeBinderException özelliğidir.

Yukarıdaki örnek, yöntemleri ve özellikleri çağırırken dinamiklerin nasıl çalıştığını gösterir. Bir başka güçlü (ve potansiyel olarak tehlikeli) özellik, farklı veri türleri için değişkenleri yeniden kullanabilmektir. Eminim Python, Ruby ve Perl programcıları bundan faydalanmak için milyonlarca yol düşünebilirler, ama ben C # 'yi çok uzun zamandır kullanıyorum.

dynamic foo = 123;
foo = "bar";

Tamam, bu yüzden büyük olasılıkla yukarıdaki gibi kod yazmayacaksınız. Bununla birlikte, değişken yeniden kullanımın kullanışlı olabileceği veya kirli bir eski kod parçasını temizleyebileceği zamanlar olabilir. Sık karşılaştığım basit bir durum, sürekli olarak ondalık ve çift arasında olmak zorunda.

decimal foo = GetDecimalValue();
foo = foo / 2.5; // Does not compile
foo = Math.Sqrt(foo); // Does not compile
string bar = foo.ToString("c");

İkinci satır derlenmez çünkü 2.5 çift olarak yazılır ve satır 3 derlenmez çünkü Math.Sqrt bir çift bekler. Açıkçası, yapmanız gereken tek şey değişken türünüzü yayınlamak ve / veya değiştirmek, ancak dinamik kullanımın mantıklı olduğu durumlar olabilir.

dynamic foo = GetDecimalValue(); // still returns a decimal
foo = foo / 2.5; // The runtime takes care of this for us
foo = Math.Sqrt(foo); // Again, the DLR works its magic
string bar = foo.ToString("c");

Daha fazla bilgi okuyun: http://www.codeproject.com/KB/cs/CSharp4Features.aspx


97
Şahsen ben dynamicstandart c # özellikleri ve statik yazarak ya da en çok tür çıkarım ( var) ile çözülebilir (belki daha iyi) sorunları çözmek için c # kullanma düşüncesini sevmiyorum . dynamicgerektiğini ancak bunun DLR ile interoperabilty konulara gelince kullanılabilir. C # gibi statik yazılan bir dilde kod yazarsanız, bunu yapın ve dinamik bir dil taklit etmeyin. Bu sadece çirkin.
Philip Daubmeier

40
dynamicKodunuzda değişkenlere ihtiyaç duymadığınız durumlarda (kare köklü örnekte olduğu gibi) çok fazla değişken kullanırsanız, derleme zamanı hata denetiminin temiz olmasını sağlarsınız; bunun yerine artık olası çalışma zamanı hataları alıyorsunuz.
Philip Daubmeier

33
Çoğunlukla iyi, ama birkaç küçük hata. İlk olarak, dinamik değişkenin türünün değişebileceği anlamına gelmez . Söz konusu değişken "dinamik" türündedir (C # dilinin bakış açısından; CLR'nin bakış açısından değişken tür nesnesidir). Değişkenin türü asla değişmez. Değişkenin değerinin çalışma zamanı türü, değişkenin türüyle uyumlu herhangi bir tür olabilir. (Veya referans türleri söz konusu olduğunda geçersiz olabilir.)
Eric Lippert

15
İkinci noktanıza gelince: C # "içine herhangi bir şey koyabileceğiniz bir değişken yapın" özelliğine sahipti - her zaman yazım nesnesinin bir değişkenini yapabilirsiniz. Dinamik ile ilgili ilginç olan şey ilk paragrafınızda işaret ettiğiniz şeydir: dinamik, nesneye neredeyse aynıdır, ancak semantik analiz çalışma zamanına ertelenir ve anlamsal analiz ifadenin çalışma zamanı türünde yapılır. (Çoğunlukla, bazı istisnalar vardır.)
Eric Lippert

18
Temelde genel kullanım için anahtar kelimenin kullanımını dolaylı olarak savunduğundan, bu konuda bir aşağı noktası harcadım. Özel olarak hedeflenmiş bir amacı vardır (Lasses'ın cevabında mükemmel bir şekilde tanımlanmıştır) ve bu cevap teknik olarak doğru olmasına rağmen, geliştiricilerin yoldan sapmasına neden olacaktır.
Sekiz Bit Gurusu

211

dynamicAnahtar kelime daha basit kod konuşmak yapmak, birlikte C # 4.0 diğer birçok yeni özellikler ile, eklendiğini yaşıyor veya farklı API'leri vardır diğer çalışma zamanları geliyor.

Bir örnek ver.

Nesne gibi bir COM nesneniz varsa Word.Applicationve bir belge açmak istiyorsanız, bunu yapmak için kullanılan yöntem, çoğu isteğe bağlı olan en az 15 parametre ile birlikte gelir.

Bu yöntemi çağırmak için, böyle bir şeye ihtiyacınız olacak (basitleştiriyorum, bu gerçek kod değil):

object missing = System.Reflection.Missing.Value;
object fileName = "C:\\test.docx";
object readOnly = true;
wordApplication.Documents.Open(ref fileName, ref missing, ref readOnly,
    ref missing, ref missing, ref missing, ref missing, ref missing,
    ref missing, ref missing, ref missing, ref missing, ref missing,
    ref missing, ref missing);

Tüm bu argümanları not ettiniz mi? Sürüm 4.0 isteğe bağlı bağımsız değişkenler kavramı yoktu önce C # geçmesi gerekir. C # 4.0'da, COM API'lerinin aşağıdakilerle birlikte çalışması daha kolay hale getirilmiştir:

  1. İsteğe bağlı argümanlar
  2. refCOM API'leri için isteğe bağlı yapma
  3. Adlandırılmış bağımsız değişkenler

Yukarıdaki çağrı için yeni sözdizimi şöyle olacaktır:

wordApplication.Documents.Open(@"C:\Test.docx", ReadOnly: true);

Ne kadar kolay göründüğüne, ne kadar okunabilir hale geldiğine bakın?

Bunu ayıralım:

                                    named argument, can skip the rest
                                                   |
                                                   v
wordApplication.Documents.Open(@"C:\Test.docx", ReadOnly: true);
                                 ^                         ^
                                 |                         |
                               notice no ref keyword, can pass
                               actual parameter values instead

Sihir, C # derleyicisinin artık gerekli kodu enjekte edeceği ve çalışma zamanında yeni sınıflarla çalışacağı, daha önce yaptığınızla aynı şeyi yapmasıdır, ancak sözdizimi sizden gizlenmiştir, şimdi ne ve nasıl çok fazla değil . Anders Hejlsberg, tipik olarak el (ler) inizi dalgalandırmak ve doğru sıralarda bazı sihirli kelimeler söylemek zorunda olduğunuz, her şeyin büyüsü üzerine bir çeşit kelime olan farklı "büyüler" çağırmanız gerektiğini söylemekten hoşlanıyor. belirli bir büyünün devam etmesini sağlamak. COM nesneleri ile konuşmak için eski API yolu çok şeydi, derleyici sizin için kodu derlemek için koaksiyel yapmak için bir sürü çember atlamak gerekiyordu.

Arabirim veya sınıfınız olmayan bir COM nesnesiyle konuşmaya çalışırsanız, sürüm 4.0'dan önce C # 'da işler daha da bozulur, sahip olduğunuz tek şey bir IDispatchreferanstır.

Ne olduğunu bilmiyorsanız IDispatch, temelde COM nesneleri için yansımasıdır. Bir IDispatcharabirim ile nesneye "Kaydet olarak bilinen yöntem için kimlik numarası nedir?" Sorusunu sorabilir ve bağımsız değişken değerlerini içeren belirli bir türde diziler oluşturabilir ve son Invokeolarak IDispatcharabirimi, yöntemi geçirerek, birlikte taramayı başardığınız bilgiler.

Yukarıdaki Kaydetme yöntemi şöyle görünebilir (bu kesinlikle doğru kod değildir):

string[] methodNames = new[] { "Open" };
Guid IID = ...
int methodId = wordApplication.GetIDsOfNames(IID, methodNames, methodNames.Length, lcid, dispid);
SafeArray args = new SafeArray(new[] { fileName, missing, missing, .... });
wordApplication.Invoke(methodId, ... args, ...);

Bütün bunlar sadece bir belge açmak için.

VB, uzun bir süre önce kutunun dışında bunun için isteğe bağlı argümanlar ve destek aldı, bu yüzden bu C # kodu:

wordApplication.Documents.Open(@"C:\Test.docx", ReadOnly: true);

temelde sadece C # ifadesi açısından VB'yi yakalamaktır, ancak sadece COM için değil, genişletilebilir hale getirerek doğru şekilde yapmaktır. Tabii ki bu VB.NET veya .NET çalışma zamanının üzerine inşa edilmiş herhangi bir dil için de kullanılabilir.

Hakkında daha fazla bilgi bulabilirsiniz. IDispatchArayüz için Wikipedia: IDispatch . Gerçekten kanlı şeyler.

Peki, bir Python nesnesiyle konuşmak isteseydiniz ne olurdu? Bunun için COM nesneleri için kullanılandan farklı bir API var ve Python nesneleri de doğada dinamik olduğundan, aramak için doğru yöntemleri, parametrelerini vb. Bulmak için yansıma sihrine başvurmanız gerekir. yansıma, Python için yazılmış bir şey, hemen hemen yukarıdaki IDispatch kodu gibi, tamamen farklı.

Ya Ruby için? Farklı bir API hala.

JavaScript? Aynı anlaşma, bunun için farklı API.

Dinamik anahtar kelime iki şeyden oluşur:

  1. C # 'daki yeni anahtar kelime, dynamic
  2. Farklı nesne türleriyle nasıl başa çıkacağını bilen, dynamicanahtar kelimenin gerektirdiği belirli bir API'yi uygulayan ve çağrıları doğru şekilde yapmak için eşleyen bir dizi çalışma zamanı sınıfı . API belgelenmiştir, bu nedenle kapsam dışında kalan bir çalışma zamanından gelen nesneleriniz varsa ekleyebilirsiniz.

dynamicAnahtar kelime, ancak, varolan herhangi bir .NET okunur kodunu değiştirmek anlamına gelmez. Tabii, bunu yapabilirsiniz , ancak bu nedenle eklenmedi ve C # programlama dilinin önünde Anders Hejlsberg ile yazarları, hala C #'ı güçlü bir şekilde yazılmış bir dil olarak gördükleri konusunda en kararlılardı ve feda etmeyecekler bu ilke.

Bu, şöyle bir kod yazabilmenize rağmen:

dynamic x = 10;
dynamic y = 3.14;
dynamic z = "test";
dynamic k = true;
dynamic l = x + y * z - k;

ve derleme, bir tür sihirli-hadi-anlamaya-ne demek istediğini-çalışma zamanı türünde bir sistem demek değildi.

Tüm amaç, diğer nesne türleri ile konuşmayı kolaylaştırmaktı.

İnternette anahtar kelime, destekçiler, rakipler, tartışmalar, rantlar, övgü, vb. Hakkında bol miktarda malzeme var.

Aşağıdaki bağlantılarla başlamanızı ve ardından daha fazla bilgi için google'ı kullanmanızı öneririm:


12
Ayrıca serileştirilmiş JSON nesnelerinin yapısının C # 'da belirtilmediği web JSON API'leri için COM'un yanı sıra yararlıdır. Örneğin, System.Web.Helpers.Json 's Decode yöntemi dinamik bir nesne döndürür .
dumbledad

"C # 'ı hala güçlü bir şekilde yazılmış bir dil olarak görüyorlar" ın yanı sıra: Eric Lippert bir açıklama olarak "güçlü bir şekilde yazılmış" hayranı değil .
Andrew Keeton

Ona katılmıyorum, ama bu bir fikir meselesi, gerçek değil. Bana "güçlü bir şekilde yazılmış", derleyicinin derleme zamanında hangi türün kullanıldığını bilmesi ve bu türler etrafında ayarlanmış kuralları uygulaması anlamına gelir. Kural denetimini ve çalışma zamanına bağlamayı erteleyen dinamik bir tür seçebilmeniz, bana göre dilin zayıf yazıldığı anlamına gelmez. Genellikle zayıf yazılanlarla güçlü bir şekilde yazılan kontrast yapmıyorum, ancak, genellikle Python gibi diller gibi dinamik olarak yazılanlarla karşılaştırıyorum, burada her şey havlayana kadar bir ördek.
Lasse V. Karlsen

Bu cevabın anlamı nedir? Bunun yarısı isteğe bağlı parametreler ve IDispatch arabirimi ile ilgilidir.
Xam

Bu yüzden dynamic , yansıma benzeri yöntem çağırma işleminin nasıl yapılabileceği konusunda diğer ekosistemleri desteklemek ve ayrıca veri yapılarına bunu başarmak için belgelenmiş bir yolla bir tür kara kutu yaklaşımı sağlamak için eklenmiştir.
Lasse V. Karlsen

29

Kimsenin birden fazla sevkiyattan bahsetmediğine şaşırdım . Bu sorunu çözmenin olağan yolu Ziyaretçi kalıbıdır ve bu her zaman mümkün değildir, bu nedenle yığılmış iskontrollerle sonuçlanırsınız .

İşte size kendi uygulamamın gerçek bir örneği. Yapmak yerine:

public static MapDtoBase CreateDto(ChartItem item)
{
    if (item is ElevationPoint) return CreateDtoImpl((ElevationPoint)item);
    if (item is MapPoint) return CreateDtoImpl((MapPoint)item);
    if (item is MapPolyline) return CreateDtoImpl((MapPolyline)item);
    //other subtypes follow
    throw new ObjectNotFoundException("Counld not find suitable DTO for " + item.GetType());
}

Siz yapıyorsunuz:

public static MapDtoBase CreateDto(ChartItem item)
{
    return CreateDtoImpl(item as dynamic);
}

private static MapDtoBase CreateDtoImpl(ChartItem item)
{
    throw new ObjectNotFoundException("Counld not find suitable DTO for " + item.GetType());
}

private static MapDtoBase CreateDtoImpl(MapPoint item)
{
    return new MapPointDto(item);
}

private static MapDtoBase CreateDtoImpl(ElevationPoint item)
{
    return new ElevationDto(item);
}

İlk durumda ElevationPointalt sınıf olduğunu MapPointve daha önce yerleştirilmemişse MapPoint . En yakın eşleştirme yöntemi çağrılacağından, bu dinamik durum için geçerli değildir.

Koddan tahmin edebileceğiniz gibi, ChartItem nesnelerinden serileştirilebilir sürümlerine çeviri yaparken bu özellik kullanışlı oldu. Kodumu ziyaretçilerle kirletmek istemedim ve ChartItemnesnelerimi yararsız serileştirmeye özgü niteliklerle kirletmek de istemedim .


Bu kullanım durumu hakkında bilmiyordum. En iyi ihtimalle biraz acayip. Herhangi bir statik analizörü atar.
Kugel

2
@Kugel bu doğru, ama buna bir hack demezdim . Statik analiz iyidir, ancak alternatiflerin olduğu şık bir çözümden uzak durmama izin vermezdim: açık-kapalı prensip ihlali (Ziyaretçi modeli) veya isüst üste korkunç yığılmış olarak artan siklomatik karmaşıklık .
Stelios Adamantidis

4
C # 7 ile desen eşleştirme seçeneğiniz var, değil mi?
Kugel

2
Operatörler bu şekilde çok daha ucuzdur (çift dökümden kaçınarak) ve statik analizi geri alırsınız ;-) ve performans.
Kugel

@ idbrii lütfen cevaplarımı değiştirmeyin. Bir yorum bırakmaktan çekinmeyin ve hala bu toplulukta aktif olduğum için (gerekirse) açıklığa kavuşacağım. Ayrıca, lütfen kullanmayın magic; sihir diye bir şey yoktur.
Stelios Adamantidis

11

Statik yazılan dillerin (CLR), DLR'de (dinamik dil çalışma zamanı) çalışan dinamik dillerle (python, ruby ​​...) birlikte çalışmasını kolaylaştırır, bkz. MSDN :

Örneğin, C # 'da XML'de bir sayacı artırmak için aşağıdaki kodu kullanabilirsiniz.

Scriptobj.SetProperty("Count", ((int)GetProperty("Count")) + 1);

DLR kullanarak, aynı işlem için aşağıdaki kodu kullanabilirsiniz.

scriptobj.Count += 1;

MSDN şu avantajları listeler:

  • Dinamik Dilleri .NET Framework'e Aktarmayı Kolaylaştırır
  • Statik Yazılan Dillerdeki Dinamik Özellikleri Etkinleştirir
  • DLR ve .NET Framework'ün Gelecekteki Avantajlarını Sağlar
  • Kütüphane ve Nesnelerin Paylaşılmasını Sağlar
  • Hızlı Dinamik Sevkıyat ve Çağırma Sağlar

Daha fazla ayrıntı için MSDN'ye bakın.


1
Ve VM için dinamik için gereken değişiklik aslında dinamik dilleri kolaylaştırır.
Dykam

2
@Dykam: VM'de değişiklik yok. DLR, .NET 2.0'a kadar sorunsuz çalışır.
Jörg W Mittag

@ Jörg, evet bir değişiklik var. DLR kısmen yeniden yazılmıştır, çünkü şimdi VM dinamik çözümleme için destek sağlamıştır.
Dykam

Biraz fazla iyimserdim, araştırmalar değişikliklerin o kadar büyük olmadığını gösterdi.
Dykam

4

Kullanım örneği:

Commun özelliği 'CreationDate' olan birçok sınıfı tüketiyorsunuz:

public class Contact
{
    // some properties

    public DateTime CreationDate { get; set; }        
}

public class Company
{
    // some properties

    public DateTime CreationDate { get; set; }

}

public class Opportunity
{
    // some properties

    public DateTime CreationDate { get; set; }

}

'CreationDate' Özelliğinin değerini alan bir commun yöntemi yazarsanız, yansıma kullanmanız gerekir:

    static DateTime RetrieveValueOfCreationDate(Object item)
    {
        return (DateTime)item.GetType().GetProperty("CreationDate").GetValue(item);
    }

'Dinamik' konseptiyle kodunuz çok daha zariftir:

    static DateTime RetrieveValueOfCreationDate(dynamic item)
    {
        return item.CreationDate;
    }

7
Ördek yazarak, güzel. Ancak, bunlar sizin türünüzse bunun için bir arayüz kullanmalısınız.
Kugel

3

COM birlikte çalışma. Özellikle bilinmiyorum. Bunun için özel olarak tasarlanmıştır.


2

Çoğunlukla RAD ve Python kurbanları tarafından kod kalitesini, IntelliSense'i yok etmek ve zaman hata tespitini derlemek için kullanılacaktır.


Alaycı bir cevap ama kolayca çok doğru. Ben sadece kod iyi çalışır sonuç ile yapıları bildirmekten kaçınmak gördüm, ama peynir hareket en kısa sürede onun yığın öngörülemez şekilde darbeler.
AnthonyVO

Evet, diğer birçok dil özelliğiyle klasik köşe kesimini göreceksiniz. Burada da görmeniz sürpriz değil.
Hawkeye4040

1

Çalışma zamanında değerlendirilir, böylece JavaScript'te olduğu gibi türü istediğiniz gibi değiştirebilirsiniz. Bu yasal:

dynamic i = 12;
i = "text";

Ve böylece türü istediğiniz gibi değiştirebilirsiniz. Son çare olarak kullanın; faydalıdır, ancak üretilen IL açısından sahnelerin altında çok şey olduğunu duydum ve bu bir performans fiyatına gelebilir.


7
Bunun "yasal" olduğunu söylemekte tereddüt ederdim. Elbette derlenecektir, bu yüzden derleyici şimdi derleyeceği ve çalışma zamanı çalıştıracağı anlamıyla "yasal kod" dur. Ama asla ben korumak kod herhangi bir kod belirli bir parça (veya ona benzeyen bir şey) görmek istemem, ya da yakın ateş bir suç olurdu.
Lasse V. Karlsen

6
Tabii, ama bu "dinamik" yerine "nesne" ile "yasal" olurdu. Burada dinamik hakkında ilginç bir şey göstermediniz.
Eric Lippert

Nesne için, yöntemlerinden herhangi birini gerçekten çağırmak için uygun türe dökmeniz gerekir ... imzayı kaybedersiniz; kodunuzun derleme hatası olmadan herhangi bir yöntemi çağırmasını ve çalışma zamanında hata vermesini sağlayabilirsiniz. Yazmak için acele etti, belirtmediğim için üzgünüm. Ve @Lasse, katılıyorum ve muhtemelen çok fazla dinamik kullanmayacağım.
Brian Mains

1
Son çare kullanım durumu açıklanmadı
Denfromufa

1

Benim için 'dinamik' tip değişkenleri en iyi kullanım örneği, son zamanlarda, ADO.NET ( SQLDataReader kullanarak ) bir veri erişim katmanı yazarken ve kod zaten yazılı eski saklı yordamları çağırıyordu oldu. İş mantığının büyük bölümünü içeren yüzlerce eski saklı yordam vardır. Veri erişim katmanımın, bazı manipülasyonlar yapmak için ( neredeyse hiçbiri olmasa da ) C # tabanlı iş mantığı katmanına bir tür yapılandırılmış veri döndürmesi gerekiyordu . Saklanan her yordam farklı veri kümeleri ( tablo sütunları ) döndürür . Bu nedenle, döndürülen verileri tutmak ve BLL'ye aktarmak için düzinelerce sınıf veya yapı oluşturmak yerine, oldukça zarif ve düzgün görünen aşağıdaki kodu yazdım.

public static dynamic GetSomeData(ParameterDTO dto)
        {
            dynamic result = null;
            string SPName = "a_legacy_stored_procedure";
            using (SqlConnection connection = new SqlConnection(DataConnection.ConnectionString))
            {
                SqlCommand command = new SqlCommand(SPName, connection);
                command.CommandType = System.Data.CommandType.StoredProcedure;                
                command.Parameters.Add(new SqlParameter("@empid", dto.EmpID));
                command.Parameters.Add(new SqlParameter("@deptid", dto.DeptID));
                connection.Open();
                using (SqlDataReader reader = command.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        dynamic row = new ExpandoObject();
                        row.EmpName = reader["EmpFullName"].ToString();
                        row.DeptName = reader["DeptName"].ToString();
                        row.AnotherColumn = reader["AnotherColumn"].ToString();                        
                        result = row;
                    }
                }
            }
            return result;
        }

0
  1. Pythonnet kullanarak CPython gibi dinamik dillere çağrı yapabilirsiniz:

dynamic np = Py.Import("numpy")

  1. dynamicÜzerine sayısal işleçler uygularken jenerikleri yayınlayabilirsiniz . Bu tip güvenliği sağlar ve jeneriklerin sınırlarını önler. Bu özünde * ördek yazarak:

T y = x * (dynamic)x, nerede typeof(x) is T


0

dynamicYazma için bir başka kullanım örneği , kovaryans veya kontravaryans ile ilgili bir sorun yaşayan sanal yöntemler içindir. Böyle bir örnek Clone, çağrıldığı nesneyle aynı türdeki bir nesneyi döndüren rezil yöntemdir. Bu sorun dinamik bir dönüşle tamamen çözülmez, çünkü statik tip kontrolünü atlar, ancak en azından düz kullanırken her zaman çirkin dökümler kullanmanıza gerek yoktur object. Aksi takdirde, atmalar örtülü olur.

public class A
{
    // attributes and constructor here
    public virtual dynamic Clone()
    {
        var clone = new A();
        // Do more cloning stuff here
        return clone;
    }
}

public class B : A
{
    // more attributes and constructor here
    public override dynamic Clone()
    {
        var clone = new B();    
        // Do more cloning stuff here
        return clone;
    }
}    

public class Program
{
    public static void Main()
    {
        A a = new A().Clone();  // No cast needed here
        B b = new B().Clone();  // and here
        // do more stuff with a and b
    }
}
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.