Home > Back-end >  Is possible to cast object type to another type inline in C#?
Is possible to cast object type to another type inline in C#?

Time:10-17

I have a program in .Net 5 C# that make a HTTP Request and the content (JSON) is deserialized (JsonNewtonsoft) in specific type:

// Class definition
public class FooSerializerModel {

    [JsonProperty("latitude")] 
    public string Latitude { get; set; }

    [JsonProperty("longitude")]
    public string Longitude { get; set; }

}

// Deserialization
var fooJson = JsonConvert.DeserializeObject<FooSerializerModel>(response);

It works fine, now, I need cast the fooJson variable type to other type for pass it to Data Layer Method:

public class DataModel {

    public string Latitude { get; set; }

    public string Longitude { get; set; }

}

I need something like this:

var data = fromJson as DataModel;

But I get this error: Cannot convert type FooSerializerModel to DataModel Why?

I know is possible solve this problem using:

var data = new DataModel() {
    Latitude = fromJson.Latitude,
    Longitude = fromJson.Longitude
}

But if my class has 50 attributes I would have to assign one by one, it would be more lines of code and I could forget some of them when doing it explicitly.

Is it possible to do an implicit assignment on a single line? I have tried this:

var data = fromJson as DataModel; // Error

var data = (DataModel) fromJson; // Error

var data = (DataModel) (object) fromJson; // Exception 'Unable to cast object of type' when use 'dotnet run'

I remember that it is possible to do this in TypeScript if you work with types with interfaces and is easy!

CodePudding user response:

All the code was tested in Visual Studio and working properly.

var fooJson = JsonConvert.DeserializeObject<DataModel>(response);

everything will be fine, since you don't really need [JsonProperty] attribute. You just need to fix your startup or there are another options to conver low case to upper.

public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews()
    .AddNewtonsoftJson(options =>
           options.SerializerSettings.ContractResolver =
              new CamelCasePropertyNamesContractResolver());

     .... other code
}

but I even don't think that json attributes will affect your classes even if you use them for MongoDB. Classes are classes, but attributes are attributes, they live a completely separate life.

But if you like it hard way I can offer this

public class DataModel 
{

    public virtual string Latitude { get; set; }

    public virtual string Longitude { get; set; }

}

public class FooSerializerModel:DataModel
{

    [JsonProperty("latitude")]
    public override string Latitude { get; set; }

    [JsonProperty("longitude")]
    public override string Longitude { get; set; }

}

Now you can write the code you wanted

var fooJson = JsonConvert.DeserializeObject<FooSerializerModel>(response);
DataModel data=fooJson;

CodePudding user response:

Assuming both your API contract and your data-layer contract expose the same properties with the same types and names, you can use an interface:

public interface ICoordinates
{
    public string Latitude { get; set; }
    public string Longitude { get; set; }
}

public class FooSerializerModel : ICoordinates
{

    [JsonProperty("latitude")] 
    public string Latitude { get; set; }

    [JsonProperty("longitude")]
    public string Longitude { get; set; }

}

public class DataModel : ICoordinates
{
    [SampleDbAttribute(ColumnName: "col_latitude")]
    public string Latitude { get; set; }

    [SampleDbAttribute(ColumnName: "col_longitude")]
    public string Longitude { get; set; }
}

Then you can cast between the inherited types because they both implement the same interface:

// Deserialization
var fooJson = JsonConvert.DeserializeObject<FooSerializerModel>(response);

var data = fromJson as DataModel;
  • Related