Mapping 2 classes with same properties - c#

I duplicated a Class1 in a Class2 with the same properties but not all ones. In my context, I have a Class1 obj (o1) initialised with values and I want to change some ones with values of a Class2 obj (o2) without losing the o1 data (values which aren't in o2). Manually, I need to reassignate o1 with values of o2 so I would like to find an automatic way like mapping the classes.
Classes:
public class Class1
{
public bool Property1;
public int Property2;
public string Property3;
public bool Property4;
public int Property5;
public string Property6;
public bool Property7;
public int Property8;
public string Property9;
public bool Property10;
public int Property11;
public string Property12;
public bool Property13;
public int Property14;
public string Property15;
public bool Property16;
public int Property17;
public string Property18;
public bool Property19;
public int Property20;
}
public class Class2
{
public bool Property1;
public int Property2;
public string Property3;
public bool Property7;
public int Property8;
public string Property9;
public bool Property10;
public int Property11;
public string Property12;
public bool Property13;
public int Property14;
public string Property15;
public bool Property16;
public int Property17;
public string Property18;
public bool Property19;
public int Property20;
public Class1 ToClass1()
{
return new Class1()
{
Property1 = Property1,
Property2 = Property2,
Property3 = Property3,
Property7 = Property7,
...
Property20 = Property20
};
}
}
If I do ToClass1(), I lose the values of Property4, Property5 and Property6 of the o1.
What I do now:
// o1 and o2 are initialised with values.
o1.Property1 = o2.Property1;
o1.Property2 = o2.Property2;
o1.Property3 = o2.Property3;
o1.Property7 = o2.Property7;
...
o1.Property20 = o2.Property20;

you need to use automapper and configure your mapping rule to ignore the properties you wont want to map.
Look at this link

Related

restrict a setter to a static list of values

I have the following models
public class CustomEvent
{
private string _tag;
public int Id { get; set; }
public int PId { get; set; }
public DateTimeOffset TimeStamp { get; set; }
public string Mentor { get; set; }
public string Type { get; set; }
public string Tag
{
get => _tag;
set
{
_tag = GetTagTypeList.GetTagType(typeof(TagType)).Contains(value) ? value : "Unspecified";
}
}
}
public static class TagType
{
public const string Unspecified = "Unspecified";
public const string AmxPersonalItemCreate = "Amx.PersonalItem.Create";
public const string AmxPersonalItemUpdate = "Amx.PersonalItem.Update";
public const string AmxPersonalItemDelete = "Amx.PersonalItem.Delete";
public const string AmxRegionCreate = "Amx.Region.Create";
public const string AmxRegionUpdate = "Amx.Region.Delete";
public const string AmxRegionDelete = "Amx.Region.Update";
}
public class GetTagTypeList
{
public static List<String> GetTagType(Type type)
{
return type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
.Select(x=>x.GetValue(null).ToString()).ToList();
}
}
The above code restricts the setter to the list of static values. However this is very inefficient, as it is reflecting over the class every single time the method [GetTagType] is called.
I now have a requirement to Create a TagType class with a private constructor, and static values.
Given the values to be expressed have "." in them, it will require a custom json serializer as well.
I have read somewhere that a solution could be to use nested classes to get values which match the string being created.
i.e. for "Amx.PersonalItem.Create" we could create a class which resemble:
public static class Amx
{
public static class PersonalItem
{
public static TagType Create { get; } = new TagType("Amx.PersonalItem.Create");
}
}
I need to integrate the above example into my CustomEvent Class.
Or any other solution that uses static values to achieve same result.
Would appreciate any help ?
How about making a static item in the class that builds the list and stores it in a static variable? That means you can build the list once no matter how many times your setter is called. You still have to search the list but you don't need to use reflection.

Convert complex Json to Object

I have a following JSON response:
{
"data": [
{
"ac_conditions": "[{\"ac_condition_group_id\":156570,\"ac_condition_group_name\":\"\u0413\u0440\u0443\u043f\u043f\u0430 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 1\",\"id\":311790,\"ac_parameter\":\"utm_source\",\"ac_operator\":\"=\",\"value\":\"google_rem\",\"is_negative\":false},{\"ac_condition_group_id\":156570,\"ac_condition_group_name\":\"\u0413\u0440\u0443\u043f\u043f\u0430 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 1\",\"id\":275094,\"ac_parameter\":\"utm_source\",\"ac_operator\":\"=\",\"value\":\"yandex_retargeting\",\"is_negative\":false}]",
"is_dt_enabled": true,
"ac_id": 162866,
"site_blocks": "[{\"id\":324164,\"name\":\"\u041d\u043e\u043c\u0435\u0440 1 \u043d\u0430 \u0441\u0430\u0439\u0442\u0435\",\"phone_type\":\"virtual\",\"numb\":\"74950238629\",\"forward_numb\":null,\"is_dt_enabled\":true,\"dt_number_pool_numbers\":[\"74951828912\",\"74950324045\",\"74950324046\",\"74950324043\",\"74950324037\",\"74951828907\",\"74950324048\",\"74950324049\",\"74951523589\",\"74953239984\"]}]"
}
],
"success": true
}
I create a class to deserealize it
public class Condition
{
public bool success;
public List<Data> data;
public class Data
{
public string ac_conditions;
public int ac_id;
public bool is_dt_enabled;
public string site_blocks;
};
}
It's working fine. What I need is to deserealize also the elements ac_conditions and site_blocks. I have created a new class but I get an exception (System.String cannot cast to List)
public class Condition
{
public bool success;
public List<Data> data;
public class Data
{
public List<ConditionCamp> ac_conditions;
public int ac_id;
public bool is_dt_enabled;
public List<SiteBlock> site_blocks;
public class ConditionCamp
{
public int ac_condition_group_id;
public string ac_condition_group_name;
public int id;
public string ac_parameter;
public string ac_operator;
public string value;
public bool is_negative;
}
public class SiteBlock
{
public int id;
public string name;
public string phone_type;
public string numb;
public string forward_numb;
public bool is_dt_enabled;
public string dt_number_pool_numbers;
}
};
}
I use this line in my code to deserialize the JSON response
JsonConvert.DeserializeObject<Models.Condition>(string_Condition);
Your JSON property "site_blocks" is a string value containing serialized JSON-data. Therefore you need a second step to unwrap/deserialize the data. If you can change the the way how the response is generated you can fix it there (return JSON in site_blocks and no string)
E.g. (using Json.net and results of second parse run are store in site_blocks_parsed)
public class Condition
{
public bool success;
public List<Data> data;
public class Data
{
public string ac_conditions;
public int ac_id;
public bool is_dt_enabled;
public string site_blocks;
public List<SiteBlock> site_blocks_parsed;
public class ConditionCamp
{
public int ac_condition_group_id;
public string ac_condition_group_name;
public int id;
public string ac_parameter;
public string ac_operator;
public string value;
public bool is_negative;
}
public class SiteBlock
{
public int id;
public string name;
public string phone_type;
public string numb;
public string forward_numb;
public bool is_dt_enabled;
public string dt_number_pool_numbers;
}
};
}
...
var condition = JsonConvert.DeserializeObject<Condition>(jsonString);
foreach (var data in condition.data) {
data.site_blocks_parsed = JsonConvert.DeserializeObject<List<SiteBlock>>(data.site_blocks);
}

c# How to transform multiple structs into 1 bigger

i have 6 structs for the player and also for the 5 bots. Everyone of them have some different variables and some that are equal to the other ones.I declare them like this
public struct Player
{
public static int Chips;
public static int Type;
public static int Power;
public static bool bot1Turn;
public static bool bot1FoldTurn;
public static AnchorStyles playerCardsAnchor = AnchorStyles.Bottom;
}
public struct Bot1
{
public static int bot1Chips;
public static int bot1Type;
public static int bot1Power;
public static bool bot1Turn;
public static bool bot1FoldTurn;
public static AnchorStyles bot1CardsAnchor = AnchorStyles.Left;
}
public struct Bot2
{
public static int bot2Chips;
public static int bot2Type;
public static int bot2Power;
public static bool bot2Turn;
public static bool bot2FoldTurn;
public static AnchorStyles bot2CardsAnchor = AnchorStyles.Right;
}
public struct Bot3
{
public static int bot3Chips;
public static int bot3Type;
public static int bot3Power;
public static bool bot3Turn;
public static bool bot3FoldTurn;
public static AnchorStyles bot3CardsAnchor = AnchorStyles.Top;
}
public struct Bot4
{
public static int bot4Chips;
public static int bot4Type;
public static int bot4Power;
public static bool bot4Turn;
public static bool bot4FoldTurn;
public static AnchorStyles bot4CardsAnchor = AnchorStyles.Bottom | AnchorStyles.Right;
}
public struct Bot5
{
public static int bot5Chips;
public static int bot5Type;
public static int bot5Power;
public static bool bot5Turn;
public static bool bot5FoldTurn;
public static AnchorStyles bot5CardsAnchor = AnchorStyles.Top | AnchorStyles.Left;
}
Later on i add the values in a static constructor :
static MainPoker()
{
Player.Chips = 100000;
Player.Power = 0;
Player.Type = -1;
Player.playerTurn = true;
Player.playerFoldTurn = false;
}
Now should i keep all the 6 structs like this, or there's some other way to put them all together ? I'm looking for something like interface but it should also be able to hold static variables .. Any suggestions ?
Structs are value types, while classes are reference types. You almost certainly want to use classes for this type of thing.
You have many properties (which you have implemented as fields) in common between players and bots, and between the different "bot numbers". You decided to give all of those properties different names, which makes it difficult to simplify the code.
Your fields are declared static. I would suggest making them instance fields (or probably instance properties).
If you make those changes, you can use inheritance to put similar things in a common base type
public class Agent
{
public int Chips;
public int Type;
public int Power;
public bool Turn;
public bool FoldTurn;
public AnchorStyles CardsAnchor;
}
public class Player : Agent
{
public Player() { CardsAnchor = AnchorStyles.Bottom; }
// Anything that makes a player different here
}
public class Bot : Agent
{
// Anything that makes a bot different here
public Bot(AnchorStyles style)
{
CardsAnchor = style;
}
}
Player player = new Player();
Bot bot1 = new Bot(AnchorStyles.Left);
Bot bot2 = new Bot(AnchorStyles.Right);
You an use properties in your code rather than fields. They will seem to behave similarly in code consuming the class, but properties afford more flexibility because they provide a layer between the value of something and how it is stored behind the scenes (for example, a property can be calculated based on the value of other properties or multiple backing fields). Using properties, you would instead write
public class Agent
{
public int Chips { get; set; }
public int Type { get; set; }
public int Power { get; set; }
public bool Turn { get; set; }
public bool FoldTurn { get; set; }
public AnchorStyles CardsAnchor { get; set; }
}
You don't want structs, you want classes (except you really want structs, but then you would know it)
and you are mixing classes with instances of classes (objects).
Generate just one Player class and then create instances from it:
public class Player
{
public int Chips { get; set; }
public int Type { get; set; }
public int Power { get; set; }
public bool BotTurn { get; set; }
public bool BotFoldTurn { get; set; }
public AnchorStyles PlayerCardsAnchor { get; }
public Player(AnchorStyles playerCardsAnchor, more parameters for properties)
{
PlayerCardsAnchor = playerCardsAnchor;
// set other properties here
}
}
MainPoker()
{
var player = new Player(AnchorStyles.Bottom, more parameters);
var bot1 = new Player(AnchorStyles.Left, more parameters);
//more bots
}
If you need a static way to acces these, create a static class that holds references to these instances.
public static class PokerTable
{
public static Player Player { get; }
public static Player Bot1 { get; }
// more bots
static PokerTable()
{
Player = new Player(AnchorStyles.Bottom, more parameters);
Bot1 = new Player(AnchorStyles.Left, more parameters);
//more bots
}
}
Then you can access the instances in a static way using
PokerTable.Player.Chips = 10;

how to generic type property

Is there a type like enum that would allow me to merge these variable into one
private string StringPropertie;
private int IntPropertie;
private float floatPropertie;
private DateTime DatetimePropertie;
private bool boolPropertie;
to something has follow.
private enumtype property
You can use structure
public struct MyStruct
{
public string StringPropertie;
public int IntPropertie;
public float floatPropertie;
public DateTime DatetimePropertie;
public bool boolPropertie;
}
public class MyClass
{
public MyClass()
{
MyStruct property ;
//...
string str = property.StringPropertie;
}
}

Load object data from XML in C#

I have the following class:
[Serializable]
public class SerialAssassin
{
public Hero hero;
public Point heroPB;
public Boss boss;
public Point bossPB;
public Attack attack;
public Point attackPB;
public HPMeter bossHP;
public Point bossHPPB;
public PPMeter heroPP;
public Point heroPPPB;
public Rectangle bossRect;
public Rectangle attackRect;
public int heroState;
public int stepRate;
public int attackDirection;
public int attackLoop;
public int contadorPaso;
public int contadorPasoBoss;
public int bossTop, bossLeft;
public int bossState;
public int bossHealth;
public int bossHPCap;
public int opa;
public int battlesWon;
public int mainBossCounter;
public int ppleft;
public bool paso;
public bool inStadium;
public bool fading;
public bool fightingMainBoss;
public bool fainted;
public string currentPokemon;
}
I'm having problems reading the data from the XML, which was written as follows:
XmlSerializer serializer = new XmlSerializer(typeof(SerialAssassin));
TextWriter textWriter = new StreamWriter(#"..\..\Resources\saveState.xml");
serializer.Serialize(textWriter, serial);
textWriter.Close();
From there, I don't quite know how to read the data. Plus the fact that the XML doesn't serialize the objects of Hero, Boss, Attack, HPMeter, PPMeter.
Hero class:
public class Hero
{
int state = 0;
int x, y;
string path;
Image img;
//methods
}
I'd be grateful if you would be so kind as to explain to me how to load those objects/primitives and then use them.
IIRC, the XmlSerializer checks for properties, not fields. (I think it can use public fields, but you really ought to switch to properties anyway) In addition, classes do not need to be marked as Serializable. (Serializable is used for others such as binary and SOAP serializers)
Replace your fields with properties with public getters and setters. In addition, make sure your other classes (such as Hero, Point, Boss) are all also serializable according to XmlSerializer's rules:
public class SerialAssassin
{
public Hero hero { get; set; }
public Point heroPB { get; set; }
public Boss boss { get; set; }
public int heroState { get; set; }
...
To deserialize, use its Deserialize method (http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.deserialize.aspx):
Stream xmlInputStream = ... //get your file stream, or TextReader, or XmlReader
XmlSerializer deserializer = new XmlSerializer(typeof(SerialAssassin));
SerialAssassin assassin = (SerialAssassin)deserializer.Deserialize(xmlInputStream)
EDIT: Looking at your sample Hero class, it's not serializing any of its values because you have declared them all to be private. Make them public instead.
public class Hero
{
public int state {get; set; }
public int x { get; set; }
public int y { get; set; }
public string path { get; set; }
[XmlIgnore]
public Image img { get; set; }
}
I suspect that Image will not be serializable, so you may want to store the image's file path (or some other identifying information) so you can save/load it. [XmlIgnore] will instruct the XmlSerializer to ignore that property so it doesn't fail during serialization/deserialization.
XmlSerializer serializer = new XmlSerializer(typeof(SerialAssassin));
SerialAssassin assassin;
using(var reader = File.OpenText(#"..\..\Resources\saveState.xml"))
{
assassin = (SerialAssassin)serializer.Deserialize(reader);
}

Categories

Resources