How to create deep-clone of DYNAMIC List? - c#

I have a List<dynamic> and I need to create clone of that. I've tried thousand way to solve it, you are the last hope.
Code looks like this:
public class Basic
{
public int Start { get; set; }
public int Leng { get; set; }
public string Name { get; set; }
}
public class MyObj
{
public Basic Basic { get; set; }
public string Value { get; set; }
}
public class MyObj1
{
public Basic Basic { get; set; }
public int Value { get; set; }
}
public class MyObj2
{
public Basic Basic { get; set; }
public string Value { get; set; }
}
public class MyObj3
{
public Basic Basic { get; set; }
public decimal Value { get; set; }
}
All this (MyObj, MyObj1, MyObj2, MyObj3) objects are in my List<dynamic> list
I need to create deep clone of List<dynamic> list.

Related

c# json with a changing class

public class 2500113075262000 {
public string pair { get; set; }
public string type { get; set; }
public double amount { get; set; }
public int rate { get; set; }
public string timestamp_created { get; set; }
public int status { get; set; }
}
public class Return {
public 2500113075262000 2500113075262000 { get; set; }
}
public class Root {
public int success { get; set; }
public Return #return { get; set; }
}
class 2500113075262000 is constantly changing, this is the order ID, like deserialize
{"success":1,"return":{"2500113075262000":{"pair":"eth_rur","type":"sell","amount":0.00110569,"rate":46100,"timestamp_created":"1608918997","status":0}}}
It looks like it's only the key - presumably the order ID - which is changing. I would suggest removing your Return class entirely, and changing your Root class to have a Dictionary<string, Order>. I'd also suggest writing your classes with idiomatic .NET property names, and using JsonPropertyAttribute to specify the representation in the JSON. So it would be something like this:
public class Order
{
[JsonProperty("pair")]
public string Pair { get; set; }
[JsonProperty("type")]
public string Type { get; set; }
// etc, other properties
}
public class Root
{
[JsonProperty("success")]
public int Success { get; set; }
[JsonProperty("return")]
public Dictionary<string, Order> Returns { get; set; }
}

Is there a way to bypass root object during deserialization?

I get a JSON response like this :
{
"xpubaddressONE":{"final_balance":123,"n_tx":0,"total_received":0},
"xpubaddressTWO":{"final_balance":25221,"n_tx":0,"total_received":0},
"xpubaddressTHREE":{"final_balance":1123,"n_tx":0,"total_received":0}
}
I want to deserialize it into C# object. I need to build classes like this :
public class xpubaddressONE
{
public int final_balance { get; set; }
public int n_tx { get; set; }
public int total_received { get; set; }
}
public class xpubaddressTHREE
{
public int final_balance { get; set; }
public int n_tx { get; set; }
public int total_received { get; set; }
}
public class xpubaddressTWO
{
public int final_balance { get; set; }
public int n_tx { get; set; }
public int total_received { get; set; }
}
public class RootObject
{
public xpubaddressONE one { get; set; }
public xpubaddressTWO two { get; set; }
public xpubaddressTHREE three { get; set; }
}
My goal is to remove additional classes(xpubaddressONE,xpubaddressTWO,xpubaddressTHREE) and access objects like this :
RootObject.final_balance
I would try deserializing a Dictionary<string, xpubaddress>, where xpubaddress is:
public class xpubaddress
{
public int final_balance { get; set; }
public int n_tx { get; set; }
public int total_received { get; set; }
}
This should then give you a dictionary with 3 keys that you can inspect with foreach, TryGetValue, etc.
Alternatively, stick with your root type, but share the inner type:
public class xpubaddress
{
public int final_balance { get; set; }
public int n_tx { get; set; }
public int total_received { get; set; }
}
public class RootObject
{
public xpubaddress xpubaddressONE{ get; set; }
public xpubaddress xpubaddressTWO{ get; set; }
public xpubaddress xpubaddressTHREE { get; set; }
}
You may also find it easier to leave the property names as idiomatic .NET names, and use [JsonProperty] or [DataMember] to rename them, i.e.
[JsonProperty("final_balance")]
public int FinalBalance { get; set; }
You can introduce the single xpubaddress class, like
public class xpubaddress
{
public int final_balance { get; set; }
public int n_tx { get; set; }
public int total_received { get; set; }
}
and then deserialize it into IDictionary<string, xpubaddress> for example, add access objects using the xpubaddressONE, xpubaddressTWO, etc., keys
var result = JsonConvert.DeserializeObject<IDictionary<string, xpubaddress>>(json);
var balance = result?["xpubaddressONE"]?.final_balance ?? 0;

Working with JSON from the AWS SDK Pricing API

I'm trying to work with AWS SDK in C# to follow and update a price catalog.
I'm using the method GetProductsAsync to list EC2 products for example, I then try to deserialize the response.
I use Json.Net to deserialize my response into a class I created using the "Paste JSON as classes" function from Visual Studio.
The object is somewhat populated, but the pricing model follows a weird JSON pattern.
Here is an extract of the object:
"terms":{
"OnDemand":{
"FBKCX9C4KX8NSVN3.JRTCKXETXF":{
"priceDimensions":{
"FBKCX9C4KX8NSVN3.JRTCKXETXF.6YS6EN2CT7":{
"unit":"Hrs",
"endRange":"Inf",
"description":"$2.47 per On Demand RHEL m4.10xlarge Instance Hour",
"appliesTo":[
],
"rateCode":"FBKCX9C4KX8NSVN3.JRTCKXETXF.6YS6EN2CT7",
"beginRange":"0",
"pricePerUnit":{
"USD":"2.4700000000"
}
}
},
The IDs under OnDemand and PriceDimensions seem to be references to other objects; therefore, they are not populated when I deserialize the JSON object, as they are different per product type.
Has anyone succeeded in getting pricing information for AWS assets?
For JSON objects having keys which can vary, you can use a Dictionary<string, T> in place of a regular class, where T is a class representing the item data. So in your case, you'd need a dictionary for both OnDemand and priceDimensions. The resulting class definitions would look like this:
public class OuterObject
{
public Terms terms { get; set; }
}
public class Terms
{
public Dictionary<string, OnDemandItem> OnDemand { get; set; }
}
public class OnDemandItem
{
public Dictionary<string, PriceDimensionsItem> priceDimensions { get; set; }
}
public class PriceDimensionsItem
{
public string unit { get; set; }
public string endRange { get; set; }
public string description { get; set; }
public object[] appliesTo { get; set; }
public string rateCode { get; set; }
public string beginRange { get; set; }
public PricePerUnit pricePerUnit { get; set; }
}
public class PricePerUnit
{
public string USD { get; set; }
}
Demo: https://dotnetfiddle.net/dJ5jmQ
Note: you could also use a Dictionary<string, string> in place of the PricePerUnit class if you will be dealing with a lot of different currencies. If there will just one or two, then having a strongly-typed class with properties for each possible currency will work fine. For example, you could add a property public string EUR { get; set; } to handle Euro.
AWS SDK have one more "level" after OnDemand.
I made my own class based on Brian Rogers answer, and i add the rest of the class to support Reserved and Products, making a nested class.
public class OuterObject
{
public Dictionary<string, Products> products { get; set; }
public Terms terms { get; set; }
}
public class Products
{
public string sku { get; set; }
public string productFamily { get; set; }
public Attributes attributes { get; set; }
}
public class Attributes
{
public string servicecode { get; set; }
public string location { get; set; }
public string locationType { get; set; }
public string instanceType { get; set; }
public string currentGeneration { get; set; }
public string vcpu { get; set; }
public string memory { get; set; }
public string operatingSystem { get; set; }
public string licenseModel { get; set; }
public string preInstalledSw { get; set; }
public string tenancy { get; set; }
}
public class Terms
{
public Dictionary<string, Dictionary<string, OnDemandItem>> OnDemand { get; set; }
public Dictionary<string, Dictionary<string, OnDemandItem>> Reserved { get; set; }
}
public class OnDemandItem
{
public string offerTermCode { get; set; }
public string sku { get; set; }
public Dictionary<string, PriceDimensionsItem> priceDimensions { get; set; }
public TermAttributes termAttributes { get; set; }
}
public class PriceDimensionsItem
{
public string unit { get; set; }
public string endRange { get; set; }
public string description { get; set; }
public object[] appliesTo { get; set; }
public string rateCode { get; set; }
public string beginRange { get; set; }
public PricePerUnit pricePerUnit { get; set; }
}
public class PricePerUnit
{
public string USD { get; set; }
}
public class TermAttributes
{
public string LeaseContractLength { get; set; }
public string OfferingClass { get; set; }
public string PurchaseOption { get; set; }
}

Rearrange a class structure for better performance

I have a class relation ship like below,
public class CollegeInfo
{
public int CollegeId { get; set; }
public Dictionary<int, DepartementInfo> DepartementInfo { get; set; }
}
public class DepartementInfo
{
public int CollegeId { get; set; }
public int DepartementId { get; set; }
public Dictionary<int, DataGridViewRowInfo> DataGridViewRowsInfo { get; set; }
}
public struct DataGridViewRowInfo
{
public string Id { get; set; }
public int CollegeId { get; set; }
public int RowID;
public int DepartementId ;
public string SpecialString { get; set; }
}
If I have a object of CollegeInfo, I will be having different DepartementInfoand in each frame will have a collection of DataGridViewRowInfo
You all can see that we have CollegeId in all class and DepartementId in two classes how can I rearrange these classed to make a better relation, If I take a single object of DataGridViewRowInfo it should have corresponding CollegeId and DepartementId?
I have done a modification in the class structure , Please let me know the first one or this one is better
public class CollegeInfo
{
public Dictionary<int, DepartementInfo> DepartementInfo { get; set; }
}
public class DepartementInfo
{
public Dictionary<int, DataGridViewRowInfo> DataGridViewRowsInfo { get; set;}
}
public class DataGridViewRowInfo
{
public string Id { get; set; }
public int CollegeId { get; set; }
public int RowID;
public int DepartementId ;
public string SpecialString { get; set; }
}
I will keep data only in DataGridViewRowInfo, Most probably I will be having at least one department and inside that one or more DataGridViewRowInfo so if I need to get detail of a specific object, for example DepartementInfo I could get it from its property. But whether it is a good practice ?

.Net - copy a list that uses class 'A' to a new list that uses class 'B' which inherits from class 'A' and adds new items\variables

I have a list that is created as follows. It uses third party wrapper that manages downloading xml information from a computer game:-
List<EveAI.Live.Asset> lst_eveai_characterabc_assets = eve_api.GetCharacterAssets();
The class definition for Asset is:-
namespace EveAI.Live
{
[TypeConverter(typeof(ExpandableObjectConverter))]
public class Asset
{
public Asset();
public ContainerType Container { get; set; }
public List<Asset> Contents { get; set; }
public double ContentsVolume { get; }
public bool IsSingleton { get; set; }
public long ItemID { get; set; }
[Obsolete("Will be removed in a future version, use LocationStation or
LocationSolarsystem or LocationConquerableStation instead")]
public Station Location { get; set; }
public ConquerableStation LocationConquerableStation { get; set; }
public int LocationID { get; set; }
public SolarSystem LocationSolarsystem { get; set; }
public Station LocationStation { get; set; }
public long Quantity { get; set; }
public int RawQuantity { get; set; }
public ProductType Type { get; set; }
public int TypeID { get; set; }
public override string ToString();
}
}
I want to copy list lst_eveai_characterabc_assets to a new list that uses class AssetUniverseIDs - that inherits class EveAI.Live.Asset Something Like:-
public class AssetUniverseIDs : EveAI.Live.Asset
{
public Int32 stationID {get;set;}
public Int32 stationTypeID { get; set; }
public Int32 corporationID { get; set; }
public Int32 solarSystemID { get; set; }
public string solarSystemName { get; set; }
public double security { get; set; }
public string securityClass { get; set; }
public Int32 constellationID { get; set; }
public Int32 regionID { get; set; }
public string regionName { get; set; }
public string stationName { get; set; }
}
But so far I am unable to copy lst_eveai_characterabc_assets to a new list that uses class AssetUniverseIDs that inherits class Assets. How could I achieve this please.
Your best bet here may be a copy constructor:
public AssetUniverseIDs(EveAI.Live.Assett original)
{
this.Container = original.Container;
this.Contents = original.Contents;
// ...
}
Then you can build a list of AssetUniverseIDs from a list of Assets like this:
List<AssetUniverseIDs> newList =
lst_eveai_characterabc_assets.Select(a => new AssetUniverseIDs(a)).ToList();
Is there a particular reason you want AssetUniverseIDs to inherit from Asset? Perhaps it would be sufficient to just have a class with an Asset as one of its properties?

Categories