2013-07-23 26 views
6

Anonim bir sınıfa ek özellikler eklemenin bir yolu var mı (veya ekstra özelliklere sahip yeni bir örnek oluştur)?Anonim bir sınıfa fazladan özellik ekleme

string cssClasses = "hide"; 
object viewData = new { @class = cssClasses }; 
if (suppliedId != null) 
{ 
    // add an extra id property to the viewData somehow... 
    // desired end result is { @id = suppliedId, @class = cssClasses } 
} 
// ... code will be passing the viewData as the additionalViewData parameter in asp.mvc's .EditorFor method 

cevap

1

sayesinde ben o bir ExpandoObject kullanarak gitmek verdi ve böyle çalışma var: Geçen çizgisi geçilecek diye MVC çalışan bunu almak için anahtar oldu

dynamic viewData = new ExpandoObject(); 
[email protected] = cssClasses; 
if (controlId != null) 
    viewData.id = controlId; 
if (title != null) 
    viewData.title = title; 
// put the result into a route value dictionary so that MVC's EditorFor (etc) can interpret it 
var additionalViewData = new RouteValueDictionary(viewData); 

O EditorFor'daki vb ekViewData parametresi olarak

Anonim bir sınıftan geçip kendime eklemem gereken durumlarda yansıma kullanıyorum (ve ExpandoObject uygulama IDictionary'inden yararlanarak). İşte çalıştığını kontrol etmek yazdığı birim test var:

[TestMethod] 
public void ShouldBeAbleToConvertAnAnonymousObjectToAnExpandoObject() 
{ 
    var additionalViewData = new {id = "myControlId", css = "hide well"}; 
    dynamic result = new ExpandoObject(); 
    var dict = (IDictionary<string, object>)result; 
    foreach (PropertyInfo propertyInfo in additionalViewData.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) 
    { 
    dict[propertyInfo.Name] = propertyInfo.GetValue(additionalViewData, null); 
    } 
    Assert.AreEqual(result.id, "myControlId"); 
    Assert.AreEqual(result.css, "hide well"); 
} 
6

Hayır, bunu yapamazsınız. Gerçi bunu yeniden tanımlayabilirsiniz: Ben dynamic olarak değiştirdim

dynamic viewData = new { @class = cssClasses }; 
if (suppliedId != null) 
{ 
    viewData = new { @class = [email protected], yourExtra = Property }; 
} 

Not. Bu sadece dynamic'a döküm yapmadan özellikleri düzenleyebilirsiniz.

+3

Evet, ya bu veya kullanım 'dynamic'' ExpandoObject' yerine :) –

+0

@ PatrykĆwiek Evet, doğru. ExpandoObject tbh'yi çok beğendim, oldukça havalı. –

+0

Niçin 'nesneyi' kodda tutmadın anlamıyorum? Söz konusu her iki isim de türden nesnelerdir. –

2

Anonim türlere fazladan özellik ekleyemezsiniz, ancak iki anonim tür kullanabilirsiniz. Eğer dynamic sevmiyorum (ve nedenleri değil vardır) ise

, bunu yapabilirsiniz:

object viewData; 
if (suppliedId == null) 
    viewData = new { @class = cssClasses, }; 
else 
    viewData = new { @id = suppliedId, @class = cssClasses, }; 

Her birine ayrı tam yazdığınız referansları tutmak istiyorsanız

nesne örneğinden sonra kullanın:

Bunun yerine,
var viewDataSimple = new { @class = cssClasses, }; 
var viewDataExtra = new { @id = suppliedId, @class = cssClasses, }; 
object viewDataToUse; 
if (suppliedId == null) 
    viewDataToUse = viewDataSimple; 
else 
    viewDataToUse = viewDataExtra; 

. Patryk gelen bir yoruma

+0

+1 Evet, tam olarak yaptığım şey buydu. Şimdi bir kaç ek özellik var, bu yüzden permütasyonların sayısı elden çıkıyor. –

+0

@JonathanMoffatt O zaman sistemde gerçekten "the ExpandoObject" sınıfını (http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx) istiyorsunuz.Dinamik 'isim alanı. Tam olarak yeni üyeler ekleyerek çalışır. Orada verdiğim bağlantıdaki örneklere bakın. Düzenleme: Ah, yeni bulduğun cevaptan yeni çıkmıştın. –

0

Sen Reflection kullanarak gereksinimi elde edebilirsiniz, Sen KeyValue Çifti tarafından yeni bir özellik ekleyebilir. ile

string cssClasses = "hide"; 
     object viewData = new { @class = cssClasses }; 
     dynamic expandoData = new ExpandoObject(); 
     var processedData = expandoData as IDictionary<String, object>; 
     if (viewData != null) 
     { 
      PropertyInfo[] properties = viewData.GetType().GetProperties(); 
      foreach (var prop in properties) 
      { 
       if (prop == null) continue; 
       object valueObj = viewData .GetType().GetProperty(prop.Name).GetValue(viewData , null); 
       processedData[prop.Name.ToString()] = valueObj; 
      } 
     }   
     processedData["AdditionalPropertyName"] = AdditionalProperty; 
     var infoJson = JsonConvert.SerializeObject(processedData); 
+0

Şimdi sağladığınız çözümü tanımlamanız yeterlidir. – DomTomCat

İlgili konular