I want to load the highscore of an XML file and spend the first place in a label. How do I manage to read the first entry and spend its value?
public class Highscore_obj
{
public string Name { get; set; }
public int Score { get; set; }
}
class Highscore
{
public Highscore_obj[] Score_array = new Highscore_obj[4];
public void LoadXmL(string path)
{
XmlDocument XML = new XmlDocument();
using (Stream s = File.OpenRead(path))
{
XML.Load(s);
}
Score_array[0].Name = "Alex";
Score_array[0].Score = 1000;
Score_array[1].Name = "Chris";
Score_array[1].Score = 940;
Score_array[2].Name = "Stefan";
Score_array[2].Score = 700;
XmlNodeList Highscores = XML.ChildNodes;
}
When I start my game the Highscore of Alex must be visible in the label.
Instead of an Array I would rather suggest using a List. Then you can use Linq to query your list and sort by score descending. I would also rather use serialization and deserialization to load and store your List to and from XML.
The code below illustrates this and should get you on the right track.
internal List<Highscore> Highscores { get; set; }
public void LoadXmL(string path)
{
List<Highscore> highscores = null;
XmlSerializer ser = new XmlSerializer(typeof(List<Highscore>));
using (XmlReader reader = XmlReader.Create(path))
{
highscores = (List<Highscore>)ser.Deserialize(reader);
}
if (highscores == null)
{
highscores = new List<Highscore>
{
new Highscore{ Name = "Alex", Score = 1000 },
new Highscore{ Name = "Chris", Score = 940 },
new Highscore{ Name = "Stefan", Score = 700 },
};
}
}
public class Highscore
{
public string Name { get; set; }
public int Score { get; set; }
}
public Highscore GetHighest()
{
return Highscores.OrderByDescending(o => o.Score).First();
}
Related
Here are the full details of my code:
public partial class Form1 : Form
{
List<Sales> sales = new List<Sales>();
BindingSource bs = new BindingSource();
public Form1()
{
InitializeComponent();
LoadCSV();
bs.DataSource = sales;
dgvSales.DataSource = bs;
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void LoadCSV()
{
string filePath = #"c:\Users\demo\Task3_shop_data.csv";
List<string> lines = new List<string>();
lines = File.ReadAllLines(filePath).ToList();
foreach (string line in lines)
{
List<string> items = line.Split(',').ToList();
Sales s = new Sales();
s.TextBook = items[0];
s.Subject = items[1];
s.Seller = items[2];
s.Purchaser = items[3];
s.purchasedPrice = float.Parse(items[4]);
s.SalePrice = items[6];
s.Rating = items[7];
sales.Add(s);
}
}
}
}
my sales class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MichaelSACU301task3
{
internal class Sales
{
public string TextBook { get; set; }
public string Subject { get; set; }
public string Seller { get; set; }
public string Purchaser { get; set; }
public float purchasedPrice { get; set; }
public string SalePrice { get; set; }
public string Rating { get; set; }
}
}
I tried launching it but the error message keeps appearing can someone please help me fix this problem.
Use float.TryParse prior to assigning to purchasedPrice property, if the value can not be converted remember it in a list. In the example below the code to read file data is in a separate class which returns a list of sales and a list of int which is used to remember invalid lines where purchasedPrice data is invalid. You should also consider validating other data and also ensure proper amount of data after performing the line split.
public class FileOperations
{
public static (List<Sales>, List<int>) LoadSalesFromFile()
{
List<Sales> sales = new List<Sales>();
List<int> InvalidLine = new List<int>();
string filePath = #"c:\Users\demo\Task3_shop_data.csv";
List<string> lines = File.ReadAllLines(filePath).ToList();
for (int index = 0; index < lines.Count; index++)
{
var parts = lines[0].Split(',');
// validate purchase price
if (float.TryParse(parts[4], out var purchasePrice))
{
Sales s = new Sales();
s.TextBook = parts[0];
s.Subject = parts[1];
s.Seller = parts[2];
s.Purchaser = parts[3];
s.purchasedPrice = purchasePrice;
s.SalePrice = parts[6];
s.Rating = parts[7];
sales.Add(s);
}
else
{
// failed to convert purchase price
InvalidLine.Add(index);
}
}
return (sales, InvalidLine);
}
}
Call the above code in your form
var (salesList, invalidLines) = FileOperations.LoadSalesFromFile();
if (invalidLines.Count > 0)
{
// use to examine bad lines in file
}
else
{
// uses sales list
}
the error sis probably due the impossiability of float.Parse() parse the items[4] in float
you may track value of items[4] using brake point in VS
I have problem with serialization and deserialization in JSON
I've made 2 tasks to read from JSON file which looks like this:
[
{
"ID": 1,
"OIB": 123456789,
"ime": "name",
"prezime": "surname",
"grad": "city"
}
]
Now I have to add another client with ID 2, with new user informations.
I can read this JSON file with no problems, but I am stuck on writing into the same file.
public struct Klijent
{
public int ID { get; set; }
public long OIB { get; set; }
public string ime { get; set; }
public string prezime { get; set; }
public string grad { get; set; }
}
"FetchClient" from JSON
public static List<Klijent> DohvatiKlijente()
{
List<Klijent> lKlijent = new List<Klijent>();
StreamReader klijent = new StreamReader("x");
string sJson = "";
using (klijent)
{
sJson = klijent.ReadToEnd();
lKlijent = JsonConvert.DeserializeObject<List<Klijent>>(sJson);
}
return lKlijent;
}
"AddClient" to JSON
OIB -> personal identificator
ID -> should go +1 with every entry of client
grad -> city
ime -> name
prezime -> surname
public static void DodavanjeKlijenata()
{
Console.Write("Unesite OIB klijenta: ");
string pOIB = Console.ReadLine();
long nullOIB = 0;
long.TryParse(pOIB, out nullOIB);
int id = 0;
Console.Write("Unesite ime klijenta: ");
string ime1 = Console.ReadLine();
Console.Write("Unesite prezime klijenta: ");
string prezime1 = Console.ReadLine();
Console.Write("Unesite grad klijenta: ");
string grad1 = Console.ReadLine();
List<Klijent> lKlijent = DohvatiKlijente();
foreach (var Klijent in lKlijent)
{
id = Klijent.ID + 1;
}
Klijent dKlijent = new Klijent()
{
ID = id,
OIB = nullOIB,
ime = ime1,
prezime = prezime1,
grad = grad1
};
var serializer = new JsonSerializer();
using (var sw = new StreamWriter("x"))
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, dKlijent);
}
}
This code does work, but it seems to delete every time my JSON file and it's format is in one line only, I would like to have it in multiple lines.
Thank you :)
There are two things that you need to do here
Ensure new Client is appended to existing list
For this you can add the new client to the List
lKlijent.Add(dKlijent);
Now you need to serialize the List, instead of lKlijent
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, lKlijent);
}
Formatting
For formatting you can use Formatting Settings. For example,
var serializer = new JsonSerializer() { Formatting = Formatting.Indented} ;
Additional Comments
1. Calculation of ID
Instead of calculating the new ID using the following loop,
foreach (var Klijent in lKlijent)
{
id = Klijent.ID + 1;
}
You could use Enumerable.Last() to get the last client in the list. For example,
var id = lKlijent?.Any()!=true? 0:lKlijent.Last().ID;
2. Rewriting DohvatiKlijente method
The DohvatiKlijente method could rewritten as
public static List<Klijent> DohvatiKlijente()
{
return JsonConvert.DeserializeObject<List<Klijent>>(File.ReadAllText("C:\\Users\\Hrvoje\\Desktop\\Polica Osiguranja MAIN\\Polica Osiguranja\\klijent.json"));
}
Similarly, writing back to file can be simplified as
var jsonString = JsonConvert.SerializeObject(lKlijent,Newtonsoft.Json.Formatting.Indented);
File.WriteAllText(outputFilePath,jsonString);
Update: I fixed it by copy pasting the working code into a new clean project. I have no idea why I was getting that bug, but as long as it's gone
I'm having problems figuring exactly how to do what I want.
In this instance, what I have is a db of merchants, and I want to be able to add venues as a list to the merchant entry in the database. For some reason I cannot figure out why, I can fetch the merchant, but cannot seem to get a hold of the id of the entry that I have fetched and then update it. (I'm having some problems with updating as well, From what I've seen I need the Id of the entry I want, and then I can update with a patch... right?)
Here is my Json class:
public class Merchant
{
[JsonProperty(PropertyName = "name")]
public string name { get; set; }
[JsonProperty(PropertyName = "venues")]
public List<Venue> venues { get; set; }
}
public class Venue
{
[JsonProperty(PropertyName = "name")]
public string name { get; set; }
[JsonProperty(PropertyName = "tills")]
public List<Till> tills { get; set; }
}
public class Till
{
[JsonProperty(PropertyName = "name")]
public string name { get; set; }
}
Here's my RavenDB Handler class's functions that are relevent:
public List<JObject> QueryFromDb(string query)
{
List<Object> objReturned;
List<JObject> jObjects = new List<JObject>();
using (IDocumentSession session = store.OpenSession())
{
objReturned = session
.Advanced.RawQuery<Object>(query)
.ToList();
}
for (var i = 0; i < objReturned.Count; i++)
{
var json = JsonConvert.SerializeObject(objReturned[i], Formatting.Indented);
jObjects.Add(JObject.Parse( json.ToString()));
}
return jObjects;
}
public String GetJsonFromDB(string query)
{
string returnStr = "";
List<JObject> myResponse = QueryFromDb(query);
for (var i = 0; i < myResponse.Count; i++)
{
var json = JsonConvert.SerializeObject(myResponse[i], Formatting.Indented);
returnStr += json.ToString();
}
return returnStr;
}
And here is me trying to get ahold of the Id of the ravendb entry:
public void UpdateMerchantList()
{
merchantGrid.Rows.Clear();
List<JObject> myResponse = ravenDB.QueryFromDb("from Merchants");
for (var i = 0; i < myResponse.Count; i++)
{
var json = JsonConvert.SerializeObject(myResponse[i], Formatting.Indented);
Merchant merchant = new Merchant(json.ToString());
if (myResponse[i].Property("Id") != null) { merchant.MyID = myResponse[i].Property("Id").ToString(); }
merchantGrid.Rows.Add(merchant.MyID, merchant.name);
}
}
For some reason, I took this code and transplanted it into a console app, and got it to work with this code:
List<JObject> result = ravenDb.QueryFromDb("from Merchants");
for(var i = 0; i < result.Count; i++)
{
Console.WriteLine(result[i].Property("Id").ToString());
}
Which does give me the exact stuff I want:
"Id": "merchants/97-A"
"Id": "merchants/98-A"
"Id": "merchants/129-A"
"Id": "merchants/130-A"
But when I transplant it backinto my form and try to add this to the datagridview I cannot see it anymore.
update: have been able to add to the list into the merchant class in the console app. Here is the code.
public void AddVenue(string idArg,Venue venue)
{
using (IDocumentSession session = store.OpenSession())
{
var merchant = session.Load<Merchant>(idArg);
List<Venue> venuesList = new List<Venue>();
if (merchant.venues == null) { session.Advanced.Patch(merchant, m => m.venues, venuesList); }
else
{
session.Advanced.Patch(merchant,
x => x.venues,
venues => venues.Add(venue));
}
session.SaveChanges();
}
}
Just so people understand what I'm talking about: here is the json that outputs from the form application:
Why?
when in console with pretty much identical code (copy pasted) I get this:
I'm getting more data from one application than the other, and I really really want the id.
I'm going to refactor the code into a wcf application I guess. Just because. Maybe I'll accidentally fix it doing that.
You can load directly the object of given class, no need to handle JSON (de)serialization yourself, unless there is a specific reason to do so.
Also, using patching is more useful when you don't want to load the document (to save bandwidth). When you already have the document loaded, you can simply change it and save the changes.
See the following code for reference:
public class Merchant
{
// note added Id property
public string Id { get; set; }
[JsonProperty(PropertyName = "name")]
public string name { get; set; }
[JsonProperty(PropertyName = "venues")]
public List<Venue> venues { get; set; }
}
public class Venue
{
[JsonProperty(PropertyName = "name")]
public string name { get; set; }
[JsonProperty(PropertyName = "tills")]
public List<Till> tills { get; set; }
}
public class Till
{
[JsonProperty(PropertyName = "name")]
public string name { get; set; }
}
public void MerchantsTest()
{
using (var store = GetDocumentStore())
{
using (var session = store.OpenSession())
{
session.Store(new Merchant { Id = "merchant-1", name = "merchant1", venues = new List<Venue> { new Venue { name = "venue-1A", tills = new List<Till> { new Till { name = "till-1A-first" } } } } });
session.Store(new Merchant { Id = "merchant-2", name = "merchant2", venues = new List<Venue> { new Venue { name = "venue-2A", tills = new List<Till> { new Till { name = "till-2A-first" } } } } });
session.SaveChanges();
}
using (var session = store.OpenSession())
{
// you can load all merchants
var merchants = session.Query<Merchant>(null, "Merchants").ToList();
// or load specific merchant by ID
var merchant2 = session.Load<Merchant>("merchant-1");
// add a venue to a loaded merchant (not using patch but simply adding the object)
merchant2.venues.Add(new Venue { name = "venue-2B", tills = new List<Till> { new Till { name = "till-2B-first" } } });
session.SaveChanges();
}
}
}
I'm not sure if I could make my code cleaner by creating a separate class for the process I'm running but I'm doing it this way because it's how I know to do it.
My main objective is to create a JSON file from data collected through HtmlAgilityPack. I've been working with this problem the last couple days but I managed to figure out a way to do it. I managed to create a JSON file with the information retrieved but it didn't divide the information into separate objects in an object array. Instead it clustered up all the data as 1 object.
This was happening because I never created the objects with the parsed html data in the string list. Instead of creating separate lists and combining them, I need to create a list of objects made from the parsed html data and add them to a list.
To test out this hypothetical method I created 3 class instances and gave them values to see if the JSON file created the desired array of objects. When tested, it created the JSON array of objects as desired.
JSON Created:
[{"FavsGTS":"GT1","FavsGPICS":"GP1","FavsRNS":"RN1","FavsPIS":"PI1","FavsIsOns":"true"},
{"FavsGTS":"GT2","FavsGPICS":"GP2","FavsRNS":"RN2","FavsPIS":"PI2","FavsIsOns":"false"},
{"FavsGTS":"GT3","FavsGPICS":"GP3","FavsRNS":"RN3","FavsPIS":"PI3","FavsIsOns":"true"}]
Now I'm trying to figure out how can I dynamically create instances based out of the collected html data.
What I had in mind was doing something like:
gamertagsFav = new List<string>(FavsGTS.Count);
gamertagsFav.AddRange(FavsGTS);
foreach(string gamertagfav in gamertagsFav)
{
//creates a class instance and adds the parsed data in the same order.
}
An example of a generated instance would be as fallows:
gamerprofileFav gpfav1 = new gamerprofileFav()
{
FavsGTS = "gt1",
FavsGPICS = "gpic1",
FavsRNS = "rn1",
FavsPIS = "pi1",
FavsIsOns = "ison1"
};
This is possible because all the parsed data is in the same order.
My code is a bit messy, but it is as fallows:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HtmlAgilityPack;
using System.Web.Script.Serialization;
using Newtonsoft.Json;
using System.IO;
namespace Parser_Test_1._0
{
public partial class Form1 : Form
{
public List<string> FavsGTS { get; private set; }
public List<string> FavsGPICS { get; private set; }
public List<string> FavsRNS { get; private set; }
public List<string> FavsPIS { get; private set; }
public List<string> FavsIsOns { get; private set; }
public List<string> allPlayers { get; private set; }
public List<string> gamertagsFav { get; private set; }
public Form1()
{
InitializeComponent();
}
public class gamerprofileFav
{
public string FavsGTS { get; set; }
public string FavsGPICS { get; set; }
public string FavsRNS { get; set; }
public string FavsPIS { get; set; }
public string FavsIsOns { get; set; }
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.Load(#"C:\Users\josec\Documents\Visual Studio 2015\Projects\THE XBOX PROJECT\Parser-Test-1.0\Parser-Test-1.0\bin\Debug\xbFrSourceCode.txt");
string datacollected1 = doc.DocumentNode.SelectNodes("//*[#id=\"favoritesContent\"]/div[2]/div[2]/ul")[0].InnerHtml;
string datacollected2 = doc.DocumentNode.SelectNodes("//*[#id=\"friendsContent\"]/div[2]/div[2]")[0].InnerHtml;
label1.Text = datacollected1;
label2.Text = datacollected2;
//StreamWriter sw = new StreamWriter("datacollected1.txt");
//sw.Write(datacollected1);
//sw.Close();
//Gamertags
HtmlAgilityPack.HtmlDocument favs = new HtmlAgilityPack.HtmlDocument();
favs.LoadHtml(datacollected1);
FavsGTS = new List<string>();
HtmlNodeCollection gts = favs.DocumentNode.SelectNodes("//li[#data-gamertag]");
foreach (var gt in gts)
{
string datagamertag = gt.Attributes["data-gamertag"].Value;
FavsGTS.Add(datagamertag);
}
listBox1.DataSource = FavsGTS;
FavsGPICS = new List<string>();
HtmlNodeCollection gpics = favs.DocumentNode.SelectNodes("//li/a[1]/img[1][#src]");
foreach (var gpic in gpics)
{
string datagpic= gpic.Attributes["src"].Value;
FavsGPICS.Add(datagpic);
}
listBox2.DataSource = FavsGPICS;
FavsRNS = new List<string>();
HtmlNodeCollection rns = favs.DocumentNode.SelectNodes("//li/div[2]/div[2]/div[1]/div[1]");
foreach (var rn in rns)
{
string datarn = rn.InnerText;
FavsRNS.Add(datarn);
}
listBox3.DataSource = FavsRNS;
FavsPIS = new List<string>();
HtmlNodeCollection pis = favs.DocumentNode.SelectNodes("//li/div[2]/div[2]/div[1]/div[2]");
foreach (var pi in pis)
{
string datapi = pi.InnerText;
FavsPIS.Add(datapi);
}
listBox4.DataSource = FavsPIS;
FavsIsOns = new List<string>();
HtmlNodeCollection isons = favs.DocumentNode.SelectNodes("//li[#data-isonline]");
foreach (var ison in isons)
{
string dataison = ison.Attributes["data-isonline"].Value;
FavsIsOns.Add(dataison);
}
listBox5.DataSource = FavsIsOns;
//Test
gamertagsFav = new List<string>(FavsGTS.Count);
gamertagsFav.AddRange(FavsGTS);
foreach(string gamertagfav in gamertagsFav)
{
}
//Merge
allPlayers = new List<string>(FavsGTS.Count + FavsGPICS.Count + FavsRNS.Count + FavsPIS.Count + FavsIsOns.Count);
allPlayers.AddRange(FavsGTS);
allPlayers.AddRange(FavsGPICS);
allPlayers.AddRange(FavsRNS);
allPlayers.AddRange(FavsPIS);
allPlayers.AddRange(FavsIsOns);
//GpsFav //+Start+
gamerprofileFav gpfav1 = new gamerprofileFav()
{
FavsGTS = "GT1",
FavsGPICS = "GP1",
FavsRNS = "RN1",
FavsPIS = "PI1",
FavsIsOns = "true"
};
gamerprofileFav gpfav2 = new gamerprofileFav()
{
FavsGTS = "GT2",
FavsGPICS = "GP2",
FavsRNS = "RN2",
FavsPIS = "PI2",
FavsIsOns = "false"
};
gamerprofileFav gpfav3 = new gamerprofileFav()
{
FavsGTS = "GT3",
FavsGPICS = "GP3",
FavsRNS = "RN3",
FavsPIS = "PI3",
FavsIsOns = "true"
};
List<gamerprofileFav> gpfavs = new List<gamerprofileFav>();
gpfavs.Add(gpfav1);
gpfavs.Add(gpfav2);
gpfavs.Add(gpfav3);
//GgsFav //-END-
listBox6.DataSource = allPlayers;
listBox7.DataSource = gamertagsFav;
//JSON Serialize
//string data = JsonConvert.SerializeObject(gpfavs);
//File.WriteAllText("data.json", data);
}
public class gpsFav
{
}
}
}
This is the Form1 when run:
The data presented in the 5 small lists is the data that I wish to assign to the generated instances in the same order they appear. That way I can create a list based out of these generated instances which I can serialize to a JSON file.
To avoid doing all of the hard work, there is already an option to deserialize a JSON object into a .NET object that you can work with, an example with your piece of code;
public class RootObject
{
public string FavsGTS { get; set; }
public string FavsGPICS { get; set; }
public string FavsRNS { get; set; }
public string FavsPIS { get; set; }
public string FavsIsOns { get; set; }
}
While you simply deserialize it by;
RootObject gamertag_sample = JsonConvert.DeserializeObject<RootObject>(jsonstr);
Of course if you pass it an array of RootObject, you'll need to replace <RootObject> with <RootObject[]> and so on with the type.
As far as I understood this was the only problem you were seeking for a solution or have I missed something?
EDIT:
With dynamic object you can create any value entry you wish, you'll need to go through a series of tasks to do so before however.
// this would contain your key,value for the generated instance.
// {example_key, "value"} would result later in myObject.example_key (returning "value")
var expandoObj = new ExpandoObject();
var eoCollection = (ICollection<KeyValuePair<string, object>>)expandoObj;
// add your key value pairs here
eoCollection.Add(new KeyValuePair<string, object>("example", "example value"));
dynamic myDynamicObject = expandoObj;
// myDynamicObject.example will return "example value", and would result in json:
// "example":"example value"
I'm trying to save a dictionary of Matrix into an Xml file.
My Matrix class attributes are :
public class Matrix
{
public int Lines { get; set; }
public int Columns { get; set; }
public double[,] Elements { get; set; }
public string name { get; set; }
}
After many attempts, I wrote this :
string fileName = dlg.FileName;
Stream writer = new FileStream(fileName,FileMode.Create);
foreach (KeyValuePair<String, Matrix> matrice in CalMat.Calculatrice.listMatrix)
{
XmlSerializer x = new XmlSerializer(matrice.GetType());
x.Serialize(writer, matrice);
}
writer.Close();
If i run this code with one matrix, the file is created, but i only have this sentence written :
<?xml version="1.0"?><KeyValuePairOfStringMatrix xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" /><?xml version="1.0"?>
I think my code is missing something but I don't know what. A write method, I guess.
Thank you for your time!
I don't think the default KeyValuePair is serializable,
try building your own KeyValuePair class:
[Serializable]
[XmlType(TypeName="MyTypeName")]
public struct KeyValuePair<T1, T2>
{
public T1 Key { get; set; }
public T2 Value { get; set; }
}
Using BinaryFormatter this is the code:
[Serializable] // mark with Serializable
public class Matrix
{
public Matrix(string name, int lines, int columns)
{
Name = name;
Lines = lines;
Columns = columns;
Elements = new double[Lines, Columns];
}
public int Lines { get; set; }
public int Columns { get; set; }
public double[,] Elements { get; set; }
public string Name { get; set; }
}
public static void Main()
{
var path = #"D:\serialize.data"; // use the path that you want
// this is an example collection
var listMatrix = new Dictionary<string, Matrix>();
listMatrix.Add("matrix_1", new Matrix("Matrix 1", 1, 2));
listMatrix.Add("matrix_2", new Matrix("Matrix 2", 2, 2));
// Serialization
var stream = new FileStream(path, FileMode.Create);
var binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(stream, listMatrix);
stream.Close();
// Deserialization
stream = new FileStream(path, FileMode.Open);
var result = (Dictionary<string, Matrix>)binaryFormatter.Deserialize(stream);
stream.Close();
}
Using XmlSerializer this is the code:
// I implement my custom KeyValuePair to serialize (because XmlSerializer can not serialize the .net KeyValuePair)
public struct CustomKeyValuePair<T1, T2>
{
public CustomKeyValuePair(T1 key, T2 value): this()
{
Key = key;
Value = value;
}
public T1 Key { get; set; }
public T2 Value { get; set; }
// here I specify how is the cast
public static explicit operator CustomKeyValuePair<T1, T2>(KeyValuePair<T1, T2> keyValuePair)
{
return new CustomKeyValuePair<T1, T2>(keyValuePair.Key, keyValuePair.Value);
}
}
// Matrix class used to Serialize with XmlSerailzer
public class Matrix
{
public Matrix() { } // need a default constructor
public Matrix(string name, int lines, int columns)
{
Name = name;
Lines = lines;
Columns = columns;
Elements = new double[Columns][];
for (int i = 0; i < Elements.Length; i++)
{
Elements[i] = new double[Columns];
}
}
public int Lines { get; set; }
public int Columns { get; set; }
public double[][] Elements { get; set; } // I use double[][] because XmlSerialzer can not serialize a two-dimensional array (double[,])
public string Name { get; set; }
}
public static void Main()
{
var path = #"D:\serialize.data"; // use the path that you want
// this is an example collection
var listMatrix = new Dictionary<string, Matrix>();
listMatrix.Add("matrix_1", new Matrix("Matrix 1", 1, 2));
listMatrix.Add("matrix_2", new Matrix("Matrix 2", 2, 2));
// Serialization
var stream = new FileStream(path, FileMode.Create);
var xmlSerializer = new XmlSerializer(typeof(CustomKeyValuePair<string, Matrix>[]));
var aux = listMatrix.Select(keyValuePair => (CustomKeyValuePair<string, Matrix>) keyValuePair).ToArray();
xmlSerializer.Serialize(stream, aux); // I serialize an array to make easy the deserailizer
stream.Close();
// Deserialization
stream = new FileStream(path, FileMode.Open);
var result = (CustomKeyValuePair<string, Matrix>[])xmlSerializer.Deserialize(stream);
stream.Close();
}