2010-06-07 14 views
25

Aşağıdaki kod harika çalışıyor. Get ve Use yöntemleri farklı derlemelerdeyse, kod bir RuntimeBinderException ile başarısız olur. Bunun nedeni, .Net çalışma zamanı sisteminin yalnızca anonim türlerin (bu örnekte <string, int>) ortaklıkları meclislerde garanti etmesinden kaynaklanmaktadır.Montaj sınırları boyunca dinamik anonim tür döndürme/tüketme

Çalışma zamanı sistemini bunun üstesinden gelmek için kandırmanın bir yolu var mı? Nesneyi hata ayıklayıcıda Use tarafında denetleyebilir ve hata ayıklayıcı ilgili özellikleri görebilir.

class Program 
{ 
    static void Main(string[] args) 
    { 
     UsePerson(); 
     Console.ReadLine(); 
    } 

    public static void UsePerson() 
    { 
     var person = GetPerson(); 

     Console.WriteLine(person.Name); 
    } 

    public static dynamic GetPerson() 
    { 
     return new { Name = "Foo", Age = 30 }; 
    } 
} 

cevap

31

Anonim bir tür yerine bir ExpandoObject kullanın. Bu güvenle montaj sınırlarını geçmeye izin vermelidir: Genel, anonim tipinde

public static dynamic GetPerson() 
{ 
    dynamic person = new ExpandoObject(); 
    person.Name = "Foo"; 
    person.Age = 30; 

    return person; 
} 

gerçekten sadece üretildikleri aynı yöntemle dahilinde kullanılmalıdır. Bir yöntemden anonim bir tür döndürmek, genel olarak, çözdüğünden daha fazla soruna neden olur.

8

Sorunun nedeni, anonim türlerin derlemeler için dahili olmasıdır. Bu nedenle Dinamik Dil Çalışma Zamanı, başka bir meclisin özelliklerine erişmenize izin vermez.

Bu post numaralı belgede bir çözüm açıklanmıştır. Montajda, diğer montajın dahili içeriğine erişmesine izin veren anonim tip tanımlayan özel bir öznitelik koyabilirsiniz.

Başka bir çözüm, bir ortak sınıfın bir nesnesini (public properties ile) döndürüyor. Bu, tabii ki, anonim tipin avantajlarını öldürecektir.

Üçüncü bir çözüm, Reed Copsey tarafından önerilen şekilde ExpandoObject kullanıyor olacaktır.

Yine de anonim türünü kullanmak istiyorsanız, anonim bir türü "süsleyen" ve sınıfını oluşturan dinamik bir sınıf yazabilirsiniz. Böyle bir sınıf, IDynamicMetaObjectProvider arayüzünü uygulamak ve yansıtılan nesneyi yansıma ile erişmek zorunda kalacaktı. Muhtemelen, bu şey zaten orada birileri tarafından uygulandı.

+0

Gönderiyi işaret eden bağlantı bozuldu –

+1

Çözüm "1" yukarıdaki yazıya aslında oldukça ilginç. Temelde [montaj: assemblyalsfo.cs'ınızda bulunan InternalsVisibleTo ("SomeOtherAssembly")] oldukça iyi çalışır. – OFConsulting

0

hazırlıksız arayüzü

http://code.google.com/p/impromptu-interface/

Eğer sınırları ötesinde anonim tip örneği kullanmasına izin Will ama imzasıyla eşleşen bir arabirim veya en azından imzasından erişilmesini istediğiniz şeyi bildirmeniz gerekir.

1

İşte fakir bir adamın geçici çözümü; Newtonsoft.Json kurtarma, seri hale getirme gidiş-dönüş olarak/çalışma grubunuza görünür dinamik tip örnekleri oluşturur.

public static class TypeExt 
{ 
    // roundtrip json serialization to enable access to dynamic members and properties originating from another assembly 
    public static T JClone<T>(this T source) { return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source)); } 
}