将动态转换为特定类型

时间:2016-06-28 06:28:28

标签: c# dynamic

我正在一个部分中检索具有不同对象类型的JSON。 我把这部分视为动态。

我需要从这个对象获取数据,所以我创建了类似于动态数据的类,如下所示:

public class SpecificObject1
{
    public string Title{get; set;}
    public object[] ViewElements{get; set}
    public object AnyAttributes{get; set;}
}

以下是我想将其转换为此特定对象的方法:

  var @switch = new Dictionary<Type, Action> {
                { typeof(x), () =>  jsonObj.Some = jsonObj.Some as SpecificObject1},
                { typeof(y), () =>  ......}
            };

使用as进行投射会返回null。

编辑: 将属性更改为实际属性

动态包含:

AnyAttributes: {object}
Title: "title"
ViewElements: object[0]

3 个答案:

答案 0 :(得分:6)

您无法更改对象的类型 - 无论是dynamic还是其他任何编译时类型。因此,即使您将jsonObj.Some as SpecificObject1分配给jsonObj.Some,也无法更改其编译时类型(在您的情况下可能为dynamic 编译时类型)。

这意味着你可以这样做:

int a = 3;
a = a as string;

这显然是无意义的。 a属于int类型,无法更改。因此,即使您*可以将a投射到string,也无法将结果(类型为sting)分配给a,因为a实际上是int类型。

同样适用于dynamic

的实例
dynamic b = a as Bar;

这仍然会评估b类型dynamic。但是,如果a之前是Bar - 实例,那么b的运行时类型肯定也是Bar。无论如何,由于b编译时类型仍为dynamic,因此无法获得任何内容 - 使其成为无操作。

编辑:为了获得您可以使用的编译时类型,您必须根据SpecificType创建jsonObj.Some的新实例:

var newValue = new SpecificObject {
    Title = jsonObj.Some.Title,
    ViewElements = jsonObj.Some.ViewElements,
    AnyAttributes = jsonObj.Some.AnyAttributes 
}

但是,您无法将此内容分配给jsonObj.Some,并期望后者在编译时为SpecificObject类型。无论如何,因为它已经是dynamic,你可以用它做你想做的一切,例如设置它的Title

jsonObj.Some.Title = "NewTitle";

你不需要任何演员。

答案 1 :(得分:1)

您可以使用Slapper.AutoMapper功能。使用MapDynamic()方法满足您的需求。

public class Person
{
    public int Id;
    public string FirstName;
    public string LastName;
}

[Test]
public void Can_Map_Matching_Field_Names_Using_Dynamic()
{
    // Arrange
    dynamic dynamicPerson = new ExpandoObject();
    dynamicPerson.Id = 1;
    dynamicPerson.FirstName = "Clark";
    dynamicPerson.LastName = "Kent";

    // Act
    var person = Slapper.AutoMapper.MapDynamic<Person>( dynamicPerson ) as Person;

    // Assert
    Assert.NotNull( person );
    Assert.That( person.Id == 1 );
    Assert.That( person.FirstName == "Clark" );
    Assert.That( person.LastName == "Kent" );
}

答案 2 :(得分:0)

当您使用as进行投射时,如果源为空或无法转换,则会将null分配给目标。所以你不能将它与值类型一起使用。如果任何一个源为null或不可转换,则此(jsonObj.Some = (SpecificObject1)jsonObj.Some)将抛出InvalidCastException

var @switch = new Dictionary<Type, Action> {
                { typeof(x), () =>  jsonObj.Some = (SpecificObject1)jsonObj.Some },
                { typeof(y), () =>  ......}
            };