Reputation: 3422
I am retrieving JSON with different object type in one part. I made this part as dynamic.
I need to get data from this object so I created class which looks the same as the dynamic data like below:
public class SpecificObject1
{
public string Title{get; set;}
public object[] ViewElements{get; set}
public object AnyAttributes{get; set;}
}
Here is how I want to convert it to this specific object:
var @switch = new Dictionary<Type, Action> {
{ typeof(x), () => jsonObj.Some = jsonObj.Some as SpecificObject1},
{ typeof(y), () => ......}
};
Casting with as
returns null.
EDIT: Changed properties to real one
dynamic contains:
AnyAttributes: {object}
Title: "title"
ViewElements: object[0]
Upvotes: 7
Views: 34933
Reputation: 2890
You can use a Slapper.AutoMapper functionality. Use MapDynamic() method for your needs.
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" );
}
Upvotes: 3
Reputation: 37095
You can´t change the type of an object - be it dynamic
or any other compile-time type. Thus even if you assign jsonObj.Some as SpecificObject1
to jsonObj.Some
you can´t change its compiletime type (probably dynamic
in your case which is a compiletime-type).
This would imply you could to this:
int a = 3;
a = a as string;
Which is obvious non-sense. a
is of type int
which can´t be changed. So even if you *could cast a
to a string
you can´t assign the result (which would be of type sting
) to a
because a
actually is of type int
.
The same applies to an instance of dynamic
:
dynamic b = a as Bar;
This will still evaluate to b
being of type dynamic
. However if a
was a Bar
-instance before, the runtime-type of b
surely is Bar
as well. Anyway you don´t get anything by this cast as the compile-time-type of b
is still dynamic
- making it a no-op.
EDIT: In order to get a compile-time type which you can use you have to create a new instance of SpecificType
based on jsonObj.Some
:
var newValue = new SpecificObject {
Title = jsonObj.Some.Title,
ViewElements = jsonObj.Some.ViewElements,
AnyAttributes = jsonObj.Some.AnyAttributes
}
However you can´t assign this to jsonObj.Some
and expect the latter to be of type SpecificObject
at compile-time. Anyway as it already is dynamic
you can do everything you want with it, for instance set its Title
:
jsonObj.Some.Title = "NewTitle";
You won´t need any cast for this.
Upvotes: 7
Reputation: 29036
When you use as
for casting, it Assigns null
to the destination if the source is null or it is not convertible. So you cannot use it with value types. Where as this(jsonObj.Some = (SpecificObject1)jsonObj.Some
) will throws InvalidCastException
if either source is null or not convertible.
var @switch = new Dictionary<Type, Action> {
{ typeof(x), () => jsonObj.Some = (SpecificObject1)jsonObj.Some },
{ typeof(y), () => ......}
};
Upvotes: 0