Yanıtlar:
dynamic
Anahtar kelime sonradan bağlanan edilmelidir değişkenleri bildirmek için kullanılır.
Geç bağlama kullanmak istiyorsanız, herhangi bir gerçek veya hayal edilen tür için, dynamic
anahtar kelimeyi kullanırsınız ve derleyici gerisini halleder.
dynamic
Anahtar kelimeyi normal bir örnekle etkileşim kurmak için kullandığınızda, DLR örneğin normal yöntemlerine geç bağlı çağrılar gerçekleştirir.
IDynamicMetaObjectProvider
Arayüz sınıf onun sonradan bağlanan davranışın kontrol altına almak için izin verir.
Eğer kullandığınız zaman dynamic
bir etkileşim için anahtar kelime IDynamicMetaObjectProvider
uygulanması, DLR çağırır IDynamicMetaObjectProvider
yöntem ve nesnenin kendisi ne yapacağını karar verir.
ExpandoObject
Ve DynamicObject
sınıfları uygulamaları vardır IDynamicMetaObjectProvider
.
ExpandoObject
bir örneğe üye eklemenizi ve bunları dynamic
müttefik olarak kullanmanızı sağlayan basit bir sınıftır .
DynamicObject
kolayca özelleştirilmiş davranış sağlamak için miras alınabilen daha gelişmiş bir uygulamadır.
Bu soruya daha net bir cevap vermeye çalışacağım, dinamik ExpandoObject
ve arasındaki farkların ne olduğunu net bir şekilde açıklayacağım DynamicObject
.
Çok çabuk dynamic
bir anahtar kelime. Kendi başına bir tür değildir. Derleyiciye tasarım zamanında statik tür denetlemesini yoksaymasını ve bunun yerine çalışma zamanında geç bağlama kullanmasını söyleyen bir anahtar sözcüktür. Yani dynamic
bu cevabın geri kalanında fazla zaman geçirmeyeceğiz .
ExpandoObject
ve DynamicObject
gerçekten türler. YÜZEYDE birbirlerine çok benziyorlar. Her iki sınıf da uygulanmaktadır IDynamicMetaObjectProvider
. Ancak, daha derine inin ve onların birbirine benzemediğini göreceksiniz.
DynamicObject, IDynamicMetaObjectProvider
geliştiricilerin dinamik dağıtım çalışmasını sağlamak için özel temel depolama ve alma davranışıyla dinamik dağıtımı destekleyen kendi özel türlerini uygulamalarına yönelik bir başlangıç noktası olması amaçlanan kısmi bir uygulamadır .
Kısacası, DLR ile kullanılabilecek KENDİ türlerinizi oluşturmak istediğinizde DynamicObject kullanın ve istediğiniz ÖZEL davranışlarla çalışın.
Örnek: Mevcut OLMAYAN bir üyeye (örneğin çalışma zamanında eklenmemiş) bir üye girişimi denendiğinde, özel bir varsayılan değer döndüren dinamik bir türe sahip olmak istediğinizi düşünün. Ve bu varsayılan, "Üzgünüm, bu kavanozda çerez yok!" Böyle davranan dinamik bir nesne istiyorsanız, bir alan bulunamadığında ne olacağını kontrol etmeniz gerekir. ExpandoObject bunu yapmanıza izin vermeyecektir. Bu nedenle, benzersiz dinamik üye çözünürlüğü (dağıtım) davranışı ile kendi türünüzü oluşturmanız ve hazır yerleşik yerine bunu kullanmanız gerekir.ExpandoObject
.
Aşağıdaki gibi bir tür oluşturabilirsiniz: (Not, aşağıdaki kod sadece örnekleme amaçlıdır ve çalışmayabilir. DynamicObject'in nasıl düzgün kullanılacağını öğrenmek için başka yerlerde birçok makale ve öğretici vardır.)
public class MyNoCookiesInTheJarDynamicObject : DynamicObject
{
Dictionary<string, object> properties = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (properties.ContainsKey(binder.Name))
{
result = properties[binder.Name];
return true;
}
else
{
result = "I'm sorry, there are no cookies in this jar!"; //<-- THIS IS OUR
CUSTOM "NO COOKIES IN THE JAR" RESPONSE FROM OUR DYNAMIC TYPE WHEN AN UNKNOWN FIELD IS ACCESSED
return false;
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
properties[binder.Name] = value;
return true;
}
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
dynamic method = properties[binder.Name];
result = method(args[0].ToString(), args[1].ToString());
return true;
}
}
Şimdi, yeni oluşturduğumuz bu hayali sınıfı, alan yoksa çok özel bir davranışa sahip dinamik bir tür olarak kullanabiliriz.
dynamic d = new MyNoCookiesInTheJarDynamicObject();
var s = d.FieldThatDoesntExist;
//in our contrived example, the below should evaluate to true
Assert.IsTrue(s == "I'm sorry, there are no cookies in this jar!")
ExpandoObject
IDynamicMetaObjectProvider
.NET Framework ekibinin tüm bu kararları sizin için verdiği FULL uygulamasıdır . Herhangi bir özel davranışa ihtiyacınız yoksa ve ExpandoObject'in sizin için yeterince iyi çalıştığını düşünüyorsanız (zamanın% 90'ı ExpandoObject
yeterince iyi). Örneğin, aşağıdakilere bakın ve ExpandoObject için tasarımcılar dinamik üye yoksa bir istisna atmayı seçti.
dynamic d = new ExpandoObject();
/*
The ExpandoObject designers chose that this operation should result in an
Exception. They did not have to make that choice, null could
have been returned, for example; or the designers could've returned a "sorry no cookies in the jar" response like in our custom class. However, if you choose to use
ExpandoObject, you have chosen to go with their particular implementation
of DynamicObject behavior.
*/
try {
var s = d.FieldThatDoesntExist;
}
catch(RuntimeBinderException) { ... }
Özetlemek gerekirse, ExpandoObject
DynamicObject'i muhtemelen sizin için çalışacak , ancak özel ihtiyaçlarınıza bağlı olmayabilecek belirli dinamik gönderme davranışlarıyla genişletmek için önceden seçilmiş bir yoldur .
Oysa, DyanmicObject
benzersiz dinamik davranışlarla kendi türlerinizi uygulamayı basit ve kolay hale getiren bir yardımcı BaseType.
Yukarıdaki örnek kaynağın çoğunun dayandığı yararlı bir öğretici.
DynamicObject
: geçersiz kılma sırasında TryGetMember
, false değerini döndürürseniz RuntimeBinderException
, var olmayan bir mülke erişmeye çalışırken a atılır. Snippet'in gerçekten çalışması için geri dönmelisiniz true
.
C # dil özelliklerine dynamic
göre bir tür bildirimi. Yani dynamic x
değişkenin x
türü vardır dynamic
.
DynamicObject
, tür IDynamicMetaObjectProvider
için belirli bağlama davranışının uygulanmasını ve bu nedenle geçersiz kılmayı kolaylaştıran bir türdür.
ExpandoObject
bir mülkiyet çantası gibi davranan bir tiptir. Yani çalışma zamanında bu tür dinamik örneklere özellikler, yöntemler vb. Ekleyebilirsiniz.
dynamic
gerçek bir tür değildir ... derleyiciye bu değişken için geç bağlamayı kullanmasını söylemek sadece bir ipucudur. dynamic
değişkenleri object
MSIL'de olduğu gibi bildirildi
Yukarıdaki örnek DynamicObject
, farkı net bir şekilde anlatmaz, çünkü temel olarak zaten sağlanan işlevselliği uygular.ExpandoObject
.
Aşağıda belirtilen iki bağlantıda DynamicObject
, gerçek türün ( XElement
aşağıdaki bağlantılarda kullanılan örnekte) korunmasının / değiştirilmesinin ve özellikler ve yöntemler üzerinde daha iyi kontrolün mümkün olduğu çok açıktır .
public class DynamicXMLNode : DynamicObject
{
XElement node;
public DynamicXMLNode(XElement node)
{
this.node = node;
}
public DynamicXMLNode()
{
}
public DynamicXMLNode(String name)
{
node = new XElement(name);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
XElement setNode = node.Element(binder.Name);
if (setNode != null)
setNode.SetValue(value);
else
{
if (value.GetType() == typeof(DynamicXMLNode))
node.Add(new XElement(binder.Name));
else
node.Add(new XElement(binder.Name, value));
}
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
XElement getNode = node.Element(binder.Name);
if (getNode != null)
{
result = new DynamicXMLNode(getNode);
return true;
}
else
{
result = null;
return false;
}
}
}