Impossible to cast void in List C# - c#

I'm trying to make a parser which will read a CSV file and add information in a List.
My problem is that when I make my loop to add in a Dictionary, the header(key) and the value(value), I have a error
"Impossible to cast void in List" (translated from French).
Code:
private List<string> header = null;
private List<string> tableauValeurs = null;
public bool ParseCSVFile(string csvPath)
{
bool result = false;
if (File.Exists(csvPath))
{
using (StreamReader sr = new StreamReader(csvPath))
{
var firsLine = sr.ReadLine();
this.header = firsLine.Split(';').ToList();
while (sr.Peek() >= 0)
{
var line = sr.ReadLine().Split(';');
this.tableauValeurs = new List<string>();
Dictionary<string, List<string>> lineDico = new Dictionary<string, List<string>>();
for (int i = 0; i < this.header.Count; i++)
{
lineDico.Add(this.header[i], ***this.tableauValeurs.Add(line[i]***);
}
}
result = true;
}
}
return result;
}
Any idea? Thanks

The method Add is a void method. It doesn't return a new list.
So, add your element into the list first, then put the list into the Dictionary.
this.tableauValeurs.Add(line[i]);
lineDico.Add(this.header[i], this.tableauValeurs);

Add returns void. You need to add your line to tableauValeurs first and then add tableauValeurs to your Dictionary

You have:
lineDico.Add(this.header[i], this.tableauValeurs.Add(line[i]));
Now; lineDico is Dictionary<string, List<string>>, so the Add method wants a string and a List<string>; this.header[i] looks fine, but this.tableauValeurs.Add(line[i]) will return void, which isn't a List<string>. So: what is the List<string> that you intended to add as the value in lineDico?

this.tableauValeurs.Add(line[i]) doesnt return a list.
Probably best to use: (no need of this if field is only in this class)
tableauValeurs.Add(line[i]));
lineDico.Add(header[i], tableauValeurs);
If you wish to have a new list associated with dictionary, move the new list declaration after for loop.

Related

Listbox DisplayValue for Newtonsoft JToken

I have a List (from Newtonsoft), and I'm trying to define a DisplayValue for Microsoft .NET list box.
List<JToken> gCollectionRequests = new List<JToken>();
//Code here to create a valid gCollectionRequests
listBox1.DataSource = gCollectionRequests;
listBox1.DisplayMember = gCollectionRequests[0]["name"].Value<string>();
The List is based on a JSON Postman collection file, whose first field is "name". That's what I want to display. The line line above doesn't break the code, it just doesn't have any effect.
An example of the gCollectionRequests:
What is the right way to define the DisplayValue from List source?
Thanks, #SriramSakthivel. That was the key. So I made a new object that incorporated my JSON collection. Is this how you would have done it?
public class CombinedJTokens
{
private int RequestCount; //Not really needed.
public JToken MyRequest;
public CombinedJTokens(int myCount, JToken myToken)
{
this.RequestCount = myCount;
this.MyRequest = myToken;
}
public string DisplayName
{
get { return string.Format("This is a JToken: {0}", MyRequest["name"].Value<string>()); }
}
}
Then, this handles filling in the listbox:
private void FillInListBoxWithRequests()
{
List<CombinedJTokens> myCombinedTokensList = new List<CombinedJTokens>();
int theCount = 0;
foreach (var item in gCollectionRequests)
{
JToken myNewJToken = item;
CombinedJTokens myCombinedJTokens = new CombinedJTokens(++theCount, item);
myCombinedTokensList.Add(myCombinedJTokens);
}
listBox1.DataSource = null;
listBox1.DataSource = myCombinedTokensList;
listBox1.DisplayMember = "DisplayName";
}
gCollectionRequests is a list of the JSON requests defined as:
List<JToken> gCollectionRequests = new List<JToken>();

Why is this ArrayList duplicating he rows

I am junior developer and I am trying to populate an ArrayList from a Dictionary. My problem is rather then adding a new record to the ArrayList it adds the new record but also overwrites the values for all the other values in the array.
So if I inspect the values as the ArrayList is being populated I see the values from the Dictionary as expected. But when that row is inserted into the ArrayList all of the existing rows are over written with the data from current Dictionary Row. So I end up with an ArrayList with several rows that are a duplicate of the last record added from the dictionary. My code is shown below. Can someone please tell me what am I doing wrong? Code below
ArrayList arrData = new ArrayList();
eSummary edata = new eSummary();
//Starts with the first 50 recods retrieved and adds them to the ArrayList. Loops thru to get remaining records
while (blnEmpty)
{
if (response.IsSuccessStatusCode)
{
string json = response.Content.ReadAsStringAsync().Result;
var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<Dictionary<string, dynamic>>(json);
for (int i = 0; i < dict.Values.Sum(x => x.Count); i++)
{
foreach (var item in dict)
{
string checkId = (dict["data"][i]["Id"]);
edata.Id = dict["data"][i]["Id"];
edata.idExternal = (dict["data"][i]["idExternal"]) == null ? "" : (dict["data"][i]["idExternal"]);
edata.Type = "Video";
edata.ownerId = (dict["data"][i]["uploadedByOwnerId"]);
edata.dateUploaded = Convert.ToDateTime((dict["data"][i]["dateUploaded"]));
edata.durationSeconds = Convert.ToDouble((dict["data"][i]["durationSeconds"]));
edata.category = (dict["data"][i]["categories"]).Count < 1 ? string.Empty : (dict["data"][i]["categories"][0]);
edata.title = (dict["data"][i]["title"]) == string.Empty ? string.Empty : (dict["data"][i]["title"]);
edata.dateRecordStarted = Convert.ToDateTime((dict["data"][i]["dateRecordStart"]));
edata.DateAPIRan = DateTime.Now;
if (CheckAutoTag(checkId, dict["data"][i]["tags"]))
{
edata.AutoTagged = true;
}
else edata.AutoTagged = false;
arrData.Add(edata);
edata is a reference type. You keep updating the values of a single object within the loop.
You need to call new eSummary() and set the values on the new object and then add that to your list.
But do note, you should not be using ArrayList in modern c#. Use a List<eSummary> instead.

C# Method is not executing sequentially

I have the below code:
public Dictionary<int, Ticket> GetNewTickets()
{
Dictionary<int, Ticket> output = new Dictionary<int, Ticket>();
foreach (KeyValuePair<int, Ticket> item in ticketStore)
{
if (!ticketStoreNew.ContainsKey(item.Key))
{
output.Add(item.Key, item.Value);
}
}
ticketStoreNew = ticketStore;
return output;
}`
It takes a dictionary, ticketStore, checks to see if it has any new elements not in ticketStoreNew and puts them in the output dictionary. Then, ticketStoreNew is set to ticketStore until ticketStore is updated with another method and this method is ran again.
However, when I include the line ticketStoreNew = ticketStore, the program returns an empty dictionary. It looks like the method is not executing sequentially and this is running prior to the for loop.
I really just need to return any new items added to the ticketStore dictionary.
EDIT
Below is the code for getting ticketStore:
public void UpdateTickets(string inputXml)
{
// If no new tickets exit
if (inputXml.Trim() == "") { return; }
//xmlString = inputXml;
// Load XML into an enumerable
XElement xelement = XElement.Parse(inputXml);
IEnumerable<XElement> xml = xelement.Elements();
foreach (var item in xml)
{
if (item.Name == "incident")
{
int id;
// If ID can be converted to INT
if (Int32.TryParse(item.Element("id").Value, out id))
{
// If ticket is not already in store create ticket and populate data
if (!ticketStore.ContainsKey(id))
{
Ticket ticket = new Ticket();
ticket.id = id;
ticket.number = Int32.Parse(item.Element("number").Value);
ticket.title = item.Element("name").Value;
ticket.description = item.Element("description").Value;
ticketStore.Add(id, ticket);
}
}
}
}
}
}
The tickets are all based on getting XML from the Samanage API.
If another method updates ticketStore then the assignment is the problem. It doesn't copy the contents of ticketStore to ticketStoreNew it sets the reference ticketStoreNew to point to the same instance as ticketStore. Thus they are the same object and always have the same contents. Try creating a new Dictionary to copy the items:
ticketStoreNew = new Dictionary<int, Ticket>(ticketStore);
Try this code:
private Dictionary<int, Ticket> ticketStoreNew =
new Dictionary<int, Ticket>(); // add this line
public Dictionary<int, Ticket> GetNewTickets()
{
Dictionary<int, Ticket> output = new Dictionary<int, Ticket>();
foreach (KeyValuePair<int, Ticket> item in ticketStore)
{
if (!ticketStoreNew.ContainsKey(item.Key))
{
output.Add(item.Key, item.Value);
ticketStoreNew.Add(item.Key, item.Value); // add this line
}
}
//ticketStoreNew = ticketStore; remove this line
return output;
}

Passing multiple selected value from a Listbox to an Array as parameters in C#

Below is my C# code to populate the multi-selected items from the listbox
List<string> listCountry = new List<string>();
for (int i = 0; i < lstCountry.Items.Count; i++)
{
if (lstCountry.Items[i]Selected)
{
countries = listCountry.Add(lstCountry.Items[i].ToString());
}
}
And I have a line to call the method to run the report with the above parameters:
retVal = CR.GetReport(Company, countries);
My question is : What data type should I define for countries since it keeps giving me error like "can't implicitly convert type 'void' to 'string'" when I define countries as
string countries = null;
What did I do wrong here? Please help, thank you very much
Sorry I didn't make it clear enough, I have another the function GetReport() which is defined as
public CrystalDecisions.CrystalReports.Engine.ReportDocument GetReport( string Company, string countries)
{
CrystalDecisions.CrystalReports.Engine.ReportDocument retVal = new rptReortData();
ReportLogon rptLog = new ReportLogon();
rptLog.logon(retVal, "Report");
retVal.SetParameterValue("P_Country", new string[] { country});
}
How do I get the value from the listbox assign to countries
You didn't provide the name of your function but I guess it's GetReport. It doesn't return any value so you can't assign the retVal. Try the below:
CR.GetReport(Company, countries);
I'm a little puzzled by your question, but I'm guessing that the CR.GetReport function is raising an exception? So your data-type for countries depends on that function.
I might make the following change:
listCountry.Add((lstCountry.Items[i] == null ? string.Empty : lstCountry.Items[i].ToString()));
List<string> listText = new List<string>();
List<string> listValue = new List<string>();
foreach (int index in ListBox1.GetSelectedIndices()) {
listText.Add(ListBox1.Items[index].Text);
listValue.Add(ListBox1.Items[index].Value);
}
You need to return retVal from your function
public CrystalDecisions.CrystalReports.Engine.ReportDocument GetReport( string Company, string countries)
{
CrystalDecisions.CrystalReports.Engine.ReportDocument retVal = new rptResearchDataDownload();
ReportLogon rptLog = new ReportLogon();
rptLog.logon(retVal, "Report");
retVal.SetParameterValue("P_Country", new string[] { country});
// ADD THIS LINE
return retVal;
}
Also you need convert the list to a string. You can do this like this:
countries = listCountry.Aggregate((list, c) => list + c + ",");

Dictionaries in C#

This program is meant to read in a csv file and create a dictionary from it, which is then used to translate a word typed into a textbox (txtINPUT) and output the result to another textbox (txtOutput).
The program doesnt translate anything and always outputs "No translation found."
I've never used the dictionary class before so I dont know where the problem is coming from.
Thanks for any help you can give me.
Dictionary<string, string> dictionary;
private void CreateDictionary()
{
//Load file
List<string> list = new List<string>();
using (StreamReader reader = new StreamReader("dictionarylist.csv"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
//Add to dictionary
dictionary = new Dictionary<string, string>();
string[] split = line.Split(',');
dictionary.Add(split[0], split[1]);
}
}
}
private void btnTranslate_Click(object sender, EventArgs e)
{
CreateDictionary();
string outputString = null;
if (dictionary.TryGetValue(txtInput.Text, out outputString))
{
txtOutput.Text = outputString;
}
else
{
txtOutput.Text = ("No translation found");
}
}
You are creating a new instance of a Dictionary each loop cycle, basically overwriting it each time you read a line. Move this line out of the loop:
// Instantiate a dictionary
var map = new Dictionary<string, string>();
Also why not load dictionary one time, you are loading it each button click, this is not efficient.
(>=.NET 3) The same using LINQ ToDictionary():
usign System.Linq;
var map = File.ReadAllLines()
.Select(l =>
{
var pair = l.Split(',');
return new { First = pair[0], Second = pair[1] }
})
.ToDictionary(k => k.First, v => v.Second);
In your while loop, you create a new dictionary every single pass!
You want to create one dictionary, and add all the entries to that:
while ((line = reader.ReadLine()) != null)
{
//Add to dictionary
dictionary = new Dictionary<string, string>(); /* DON'T CREATE NEW DICTIONARIES */
string[] split = line.Split(',');
dictionary.Add(split[0], split[1]);
}
You should do it more like this:
List<string> list = new List<string>();
dictionary = new Dictionary<string, string>(); /* CREATE ONE DICTIONARY */
using (StreamReader reader = new StreamReader("dictionarylist.csv"))
{
string line;
while ((line = reader.ReadLine()) != null)
{
string[] split = line.Split(',');
dictionary.Add(split[0], split[1]);
}
}

Categories