向匿名类添加额外的属性
本文关键字:属性 添加 | 更新日期: 2023-09-27 18:24:29
有没有办法向匿名类添加额外的属性(或者用额外的属性创建一个新实例)?
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
不,你不能这样做。不过你可以重新定义它:
dynamic viewData = new { @class = cssClasses };
if (suppliedId != null)
{
viewData = new { @class = viewData.@class, yourExtra = Property };
}
请注意,我已将其更改为dynamic
。这只是为了在不强制转换为dynamic
的情况下编辑属性。
您不能向匿名类型添加额外的属性,但可以使用两个匿名类型。
如果你不喜欢dynamic
(有理由不喜欢),你可以这样做:
object viewData;
if (suppliedId == null)
viewData = new { @class = cssClasses, };
else
viewData = new { @id = suppliedId, @class = cssClasses, };
如果你想保留对每个对象实例的单独的精确类型的引用,那么使用:
var viewDataSimple = new { @class = cssClasses, };
var viewDataExtra = new { @id = suppliedId, @class = cssClasses, };
object viewDataToUse;
if (suppliedId == null)
viewDataToUse = viewDataSimple;
else
viewDataToUse = viewDataExtra;
相反。
感谢Patryk的评论,我尝试使用ExpandoObject,并使其像这样工作:
dynamic viewData = new ExpandoObject();
viewData.@class = 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);
最后一行是让它在MVC中工作的关键,这样它就可以作为EditorFor等中的附加ViewData参数传递。
在我被传递一个匿名类并需要自己添加到其中的情况下,我使用反射(并利用ExpandoObject实现IDictionary)。这是我为检查它是否有效而写的单元测试:
[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");
}
您可以通过使用Reflection来实现需求,您可以通过KeyValue Pair添加新属性。
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);