Unable to use ICollection.ToList() - c#

I am trying to call ToList() here:
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
namespace CSVStuff
{
public static class CSVContentGenerator
{
public static string GetContent(IOrderedDictionary headingsPropertiesMapping)
{
var propertyNames = headingsPropertiesMapping.Keys.ToList(); //ICollection does not contain a definition for ToList()
//var propertyNames = new List<object>(headingsPropertiesMapping.Keys); //Cannot convert from ICollection to int
return "";
}
}
}
Why are these not working?

Try this:
var propertyNames = headingsPropertiesMapping.Keys.Cast<T>().ToList();
and type T is the type of dictionary keys.

Related

Converting a json string to a public ulong

I need to use a string from a json file as an ulong, and then use that varialble in a different class. I tried parsing it to be a uint, but the public ulong is then said to be unused, even though it seems as if it's being used to me. This might be super obvious but I'm new to c#.
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MinecraftClient
{
class Utilities
{
private static Dictionary<string, string> whitelisted;
static Utilities()
{
string json = File.ReadAllText("whitelists/walls.json");
var data = JsonConvert.DeserializeObject<dynamic>(json);
whitelisted = data.ToObject<Dictionary<string, string>>();
}
public static ulong GetWhitelisted(string key)
{
if (whitelisted.ContainsKey(MinecraftClient.ChatBots.WeeWoo.username))
{
ulong whitelistedid;
bool parsed = UInt64.TryParse(key, out whitelistedid);
}
return 0;
}
public static ulong whitelistedid;
}
}
Inside your if block you are declaring a new variable named whitelistedid (and you're creating a variable named parsed), but they are never used and the method always returns 0.
Instead you probably want to do something like:
public static ulong GetWhitelisted(string key)
{
if (whitelisted.ContainsKey(MinecraftClient.ChatBots.WeeWoo.username))
{
ulong userWhiteListId;
if (UInt64.TryParse(key, out userWhiteListId))
{
// If parsing succeeded, return the value
return userWhiteListId;
}
// Optionally, return some other value if the user was found but parsing failed
// return -1;
}
// Either the user wasn't found or the parsing failed
return 0;
}
It looks to me that rather than having a public static variable you actually just want to return the ulong from your static method. Probably something more like...
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MinecraftClient
{
class Utilities
{
private static Dictionary<string, string> whitelisted;
static Utilities()
{
string json = File.ReadAllText("whitelists/walls.json");
var data = JsonConvert.DeserializeObject<dynamic>(json);
whitelisted = data.ToObject<Dictionary<string, string>>();
}
public static ulong GetWhitelisted(string key)
{
if (whitelisted.ContainsKey(MinecraftClient.ChatBots.WeeWoo.username))
{
ulong parsedId;
if (UInt64.TryParse(key, out parsedId))
return parsedId;
}
return 0;
}
}
}
Then to get your whitelist you would do...
var whileListId = Utilities.GetWhiteListed("someKey");

Importing CSV File in C# Convert the string list to specific classtype list

First i have to mention that iam not that good in programming but i try my best.
Following situation: I imported several csv files into string lists. Now i want to cast those lists as the classdatatype i need. For example class Student, in the studentlistmanager class iam improting the list and trying to convert it to List but it seems like it wont be that easy, i tried to create an object of that list and add the object to the student list but that wont work either. Instead of the values i get System.String[] values into my list.
internal void ImportStudentList(CsvImportService csv)
{
List<string> newList = new List<string>();
csv = new CsvImportService("Klassenlisten_20160906.csv");
for(int i = 0; i <= csv.ClassList.Count;i++)
{
for(int x = 0; x <= csv.ClassList.Count;x++)
{
string line = csv.ClassList[i];
// Student st = new Student(line);
// ListOfStudents.Add(st);
newList.Add(line);
ListOfStudents = newList.Cast<Student>().ToList();
}
}
}
I would really appreciate any help. Thanks in advance!
Is that what you are looking for ? Saving the Data of the csv File in the Student
List.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace Stackoverflow_Konsole_Test
{
class Program
{
static void Main(string[] args)
{
string CSV_FILE_PATH = #"filepath.csv";
List<string> FULL_CSV_STRING = new List<string>();
Students Student1 = new Students();
FULL_CSV_STRING.Add(File.ReadAllText(CSV_FILE_PATH));
foreach (string line in FULL_CSV_STRING)
{
Student1.add(line);
}
foreach (string line in Student1.getlist())
{
Console.WriteLine(line);
}
Console.ReadLine();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Stackoverflow_Konsole_Test
{
class Students
{
private List<string> List_of_students = new List<string>();
public Students()
{
//constructor
}
public void add(string line)
{
this.List_of_students.Add(line);
}
public List<string> getlist()
{
return this.List_of_students;
}
}
}

How do I get all the fields using json.net?

A third party is giving me something similar to the below. When I know the key (such as easyField) getting the value is easy. Below I write it in the console. However the third party gave me json that uses random keys. How do I access it?
{
var r = new Random();
dynamic j = JsonConvert.DeserializeObject(string.Format(#"{{""{0}"":""hard"", ""easyField"":""yes""}}", r.Next()));
Console.WriteLine("{0}", j["easyField"]);
return;
}
You can use reflection with JSON.NET! It will give you the keys of your fields.
Try it online: Demo
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class Program
{
public IEnumerable<string> GetPropertyKeysForDynamic(dynamic jObject)
{
return jObject.ToObject<Dictionary<string, object>>().Keys;
}
public void Main()
{
var r = new Random();
dynamic j = JsonConvert.DeserializeObject(string.Format(#"{{""{0}"":""hard"", ""easyField"":""yes""}}", r.Next()));
foreach(string property in GetPropertyKeysForDynamic(j))
{
Console.WriteLine(property);
Console.WriteLine(j[property]);
}
}
}
Edit:
An even simpler solution:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
public class Program
{
public void Main()
{
var r = new Random();
dynamic j = JsonConvert.DeserializeObject(string.Format(#"{{""{0}"":""hard"", ""easyField"":""yes""}}", r.Next()));
foreach(var property in j.ToObject<Dictionary<string, object>>())
{
Console.WriteLine(property.Key + " " + property.Value);
}
}
}
This is what I had used in my project to get fields and values of a class:
public static List<KeyValuePair> ClassToList(this object o)
{
Type type = o.GetType();
List<KeyValuePair> vals = new List<KeyValuePair>();
foreach (PropertyInfo property in type.GetProperties())
{
if (!property.PropertyType.Namespace.StartsWith("System.Collections.Generic"))
{
vals.Add(new KeyValuePair(property.Name,(property.GetValue(o, null) == null ? "" : property.GetValue(o, null).ToString()))
}
}
return sb.ToString();
}
Note that the reason I was checking !property.PropertyType.Namespace.StartsWith("System.Collections.Generic") as It was causing infinte loops in entity models and if that is not the case you can remove the if condition.

How do I get the index of string variable value into ObservableCollection?

In my windows phone application I am using observablecollection like below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Phone.UserData;
using System.Windows.Media;
using Microsoft.Phone.Maps.Controls;
using System.Collections.ObjectModel;
using System.Collections;
namespace GetContacts
{
public partial class createGroups : PhoneApplicationPage
{
string buttonName = "";
public static ObservableCollection<Group> groupbtn;
public createGroups()
{
InitializeComponent();
groupbtn = new ObservableCollection<Group>();
}
private void btn_Click(object sender, RoutedEventArgs e)
{
string buttonText = "abc"
string index = groupbtn.IndexOf(buttonText);
}
}
}
And below is the Group class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using GetContacts.Resources;
using Microsoft.Phone.UserData;
namespace GetContacts
{
public class Group
{
public string Name { get; set; }
/*public string content { get; set; }
private string[] numberofbtns = new string[5];
public string[] NumberOfBtns
{
get { return numberofbtns; }
set { numberofbtns = value; }
}*/
//object[] array1 = new object[5];
public Group()
{
}
public Group(Button btn)
{
Name = btn.Name;
}
}
}
But its getting me two errors below:
Error 1: at this line groupbtn.IndexOf(buttonText):
The best overloaded method match for 'System.Collections.ObjectModel.Collection<GetContacts.Group>.IndexOf(GetContacts.Group)' has some invalid arguments
Error 2 at this line groupbtn.IndexOf(buttonText) on it buttonText:
Argument 1: cannot convert from 'string' to 'GetContacts.Group'
How do I resolve it or kindly suggest me how do I get the index of string variable value into observablecollection.
Waiting for your reply.
Thanks.
You cannot use IndexOf with a string on an ObservableCollection<Group>. You need a Group. You also have to override Equals in class Group (also override GetHashCode):
public class Group
{
public string Name { get; set; }
public override bool Equals(object obj)
{
Group g2 = obj as Group;
return g2 != null && g2.Name == this.Name;
}
public override int GetHashCode()
{
return Name == null 0 : Name.GetHashCode();
}
}
Now you're able to use IndexOf:
Group searchGroup = new Group { Name = buttonText };
int index = groupbtn.IndexOf(searchGroup);
or use a different approach, for example using LINQ:
int index = groupbtn
.Select((g, i) => new { Group = g, Index = i })
.Where(x => x.Group.Name == buttonText)
.Select(x => x.Index)
.DefaultIfEmpty(-1)
.First();
Those are the same error. The problem is that you have a collection of type Group and then you are trying to find a matching Group with a string. You have to pass a Group to .IndexOf to find the index of the Group you are trying to find.
This type of error is something you need to be able to figure out yourself from the compiler error.
The best overloaded method match for 'System.Collections.ObjectModel.Collection<GetContacts.Group>.IndexOf(GetContacts.Group)' has some invalid arguments
This clearly means it doesn't like the argument you are passing to this function. It shows the function definition, so you can tell it wants to be passed a Group.
Argument 1: cannot convert from 'string' to 'GetContacts.Group'
You are passing a string to a function that we know accepts a Group. Since it only accepts a Group, it tries to implicitly convert the string to a Group, but there isn't a way for it automatically do that.
The IndexOf method is expecting a Group object, but you're providing a string. ObservableCollections implement IEnumerable, so you may be able to use a Linq expression. Such as...
Group btnGroup = (from g in groupbtn where g.Name == "name" select g).First();
int indexOfGroupButton = groupbtn.IndexOf(btnGroup);
Or something like that. Basically, you first need to find the actual "Group" object, and then you can find the index of that object.

Compiled class in compiling file

I have a promblem with run-time compiled classes. I have something like this 2 classes:
first class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Program.Bullet {
public class Class1{
private int i;
public Class1(int j){
i=j;
}
}
}
and second class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Program.Bullet;
namespace Program.Object {
public class Class2{
public Class2(){
Class1 c1 = new Class1(5);
}
}
}
This two classes I would like to compile in run-time and use them in my project. So I have function to compile it (XmlNode has data about fullPath etc):
private ModuleBuilder moduleBuilder;
private List<string> isCompiled;
private void Compile(XmlNode compileingClasses) {
foreach (XmlNode compileingClass in compileingClasses) {
string fullPath = compileingClass.Attributes["path"].InnerText;
string type = compileingClass.Attributes["name"].InnerText; ;
if (!isCompiled.Contains(type)) {
isCompiled.Add(type);
var syntaxTree = SyntaxTree.ParseFile("../../File1/File2/" + fullPath);
var comp = Compilation.Create("Test.dll"
, syntaxTrees: new[] { syntaxTree }
, references: metadataRef
, options: comilationOption
);
// Runtime compilation and check errors
var result = comp.Emit(moduleBuilder);
if (!result.Success) {
foreach (var d in result.Diagnostics) {
Console.WriteLine(d);
}
throw new XmlLoadException("Class not found " + fullPath);
}
}
}
}
Is it possible to get the reference on Class1 to Class2?
Edit: Better question
Is it possible to create MetadataReference on compiled Class1?
Something like:
string fullName = bullet.Attributes["fullName"].InnerText;
var o = moduleBuilder.GetType(fullName);
metadataRef.Add(new MetadataFileReference(o.Assembly.Location));
This throw NotSupportedException
You're trying to reference the assembly which is currently being built and I don't think Roslyn can do that.
What you can do instead is to create a single Compilation from all your classes (probably having a separate SyntaxTree for each class). If you do that, you won't need any references.

Categories