2017-03-16 59 views
1

我有一个类MyClass。我想将其转换为动态对象,以便我可以添加属性。转换类为动态并添加属性

这是我所希望的:

dynamic dto = Factory.Create(id); 
dto.newProperty = "123"; 

我得到的错误:

WEB.Models.MyClass does not contain a definition for 'newProperty' 

那是不可能的?

+7

动态并不意味着你可以在旅途中添加属性。这意味着你不知道它会是什么,所以你使用动态(据我所知)和类型将在运行时计算出来。 – EpicKip

+0

如果要添加属性,则需要使用[ExpandoObject](https://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject(v = vs.110).aspx)。这是一个[链接](http://stackoverflow.com/questions/3540161/c-sharp-4-0-dynamic-vs-expando-where-do-they-fit)与一些信息可能有所帮助。 – MaKCbIMKo

回答

2

以下为我工作在过去的:
它可以让你的任何对象转换为Expando的对象。

public static dynamic ToDynamic<T>(this T obj) 
{ 
    IDictionary<string, object> expando = new ExpandoObject(); 

    foreach (var propertyInfo in typeof(T).GetProperties()) 
    { 
     var currentValue = propertyInfo.GetValue(obj); 
     expando.Add(propertyInfo.Name, currentValue); 
    } 
    return expando as ExpandoObject; 
} 

基于:http://geekswithblogs.net/Nettuce/archive/2012/06/02/convert-dynamic-to-type-and-convert-type-to-dynamic.aspx

+0

这是接近我想要的,但我得到一个错误:类型'System.Guid'的表达式不能用于返回类型'系统。字符串' – Sean

+0

表达式树对'expando.Add(propertyInfo.Name,propertyInfo.GetValue(obj))'有什么优势?为什么它将属性名称转换为小写?为什么在返回时将'ExpandoObject'投射到'ExpandoObject'? – chris

+0

@Sean查看更新后的回答者 – StfBln

1

您无法在运行时向类型添加属性。但是,有一个例外是:ExpandoObject。因此,如果您需要在运行时添加属性,则应使用ExpandoObject,其他类型不支持此属性。

1

不能添加成员类的实例在运行。您可以使用ExpandoObject。使用工厂创建新的,与你在MyClass属性初始化:

public static ExpandoObject Create(int id) 
{ 
    dynamic obj = new ExpandoObject(); 
    obj.Id = id; 
    obj.CreatedAt = DateTime.Now; 
    // etc 
    return obj; 
} 

然后你就可以添加新成员:

dynamic dto = Factory.Create(id); 
dto.newProperty = "123"; 
0

正如我的对象有JSON特定的命名,我想出了这是一种替代方案:

public static dynamic ToDynamic(this object obj) 
{ 
    var json = JsonConvert.SerializeObject(obj); 
    return JsonConvert.DeserializeObject(json, typeof(ExpandoObject)); 
} 

对我来说,结果有很大的工作:

型号:

public partial class Settings 
{ 
    [JsonProperty("id")] 
    public int Id { get; set; } 

    [JsonProperty("runTime")] 
    public TimeSpan RunTime { get; set; } 

    [JsonProperty("retryInterval")] 
    public TimeSpan RetryInterval { get; set; } 

    [JsonProperty("retryCutoffTime")] 
    public TimeSpan RetryCutoffTime { get; set; } 

    [JsonProperty("cjisUrl")] 
    public string CjisUrl { get; set; } 

    [JsonProperty("cjisUserName")] 
    public string CjisUserName { get; set; } 

    [JsonIgnore] 
    public string CjisPassword { get; set; } 

    [JsonProperty("importDirectory")] 
    public string ImportDirectory { get; set; } 

    [JsonProperty("exportDirectory")] 
    public string ExportDirectory { get; set; } 

    [JsonProperty("exportFilename")] 
    public string ExportFilename { get; set; } 

    [JsonProperty("jMShareDirectory")] 
    public string JMShareDirectory { get; set; } 

    [JsonIgnore] 
    public string Database { get; set; } 
} 

我用它以这种方式:

private static dynamic DynamicSettings(Settings settings) 
{ 
    var settingsDyn = settings.ToDynamic(); 
    if (settingsDyn == null) 
    return settings; 
    settingsDyn.guid = Guid.NewGuid(); 
    return settingsDyn; 
} 

而且收到此结果:

{ 
    "id": 1, 
    "runTime": "07:00:00", 
    "retryInterval": "00:05:00", 
    "retryCutoffTime": "09:00:00", 
    "cjisUrl": "xxxxxx", 
    "cjisUserName": "xxxxx", 
    "importDirectory": "import", 
    "exportDirectory": "output", 
    "exportFilename": "xxxx.xml", 
    "jMShareDirectory": "xxxxxxxx", 
    "guid": "210d936e-4b93-43dc-9866-4bbad4abd7e7" 
} 

我不知道速度,我的意思是序列化和反序列化,但对我来说它是非常棒的。像JsonIgnore一样隐藏属性的灵活性很多。

注意:上面的xxxxx是编辑。 :)