Hello i am trying to save an object that i have been created and its returning to me error: "represents as a series of Unicode character" on this line: System.IO.File.WriteAllLines(#"C:\Users\1\AppData\Roaming\MYDATA\hi.txt", somOne);
here is the code:
main class:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Persone somOne = new Persone("bob", 5, 200);
System.IO.Directory.CreateDirectory(#"C:\Users\1\AppData\Roaming\MYDATA");
// the Error line Is HERE \/
System.IO.File.WriteAllLines(#"C:\Users\1\AppData\Roaming\MYDATA\hi.txt", somOne);
}
}
}
persone class:
namespace ConsoleApplication1
{
class Persone
{
private String name;
private int id;
private int age;
public Persone(String name, int id, int age)
{
setName(name);
setId(id);
setAge(age);
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public void setId(int id)
{
this.id = id;
}
public int getId()
{
return id;
}
public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return age;
}
}
}
do i need to chang the type of "somOne"? and how?
System.IO.File.WriteAllLines expects array of strings (or IEnumerable<string>) as second parameter, so code you have should not even compile. You can add to your Person class something like:
public string[] ToStringArray()
{
//And put it everything you need to store
return new[] {name, id.ToString(), age.ToString()};
}
and call like this:
System.IO.File.WriteAllLines(#"C:\Users\1\AppData\Roaming\MYDATA\hi.txt", somOne.ToStringArray());
You can't just save an object like that. They don't automatically format themselves for save to disk.
You want to look into either Serialization or override the .ToString() method for the class and use File.WriteAllText() instead.
According to MSDN, File.WriteAllLines requires an IEnumerable<string> or a string[] as input (the full signature is File.WriteAllLines(string, IEnumberable<string>) or File.WriteAllLines(string, string[]) where the first string is the path and the second is the set of lines you wish to write.
Passing your Persone object is not the same. At the very least you would need to override .ToString() on your object, better might be to write a new method .WritePersone() or something like that.
With the first, you'd call WriteAllLines like this:
System.IO.File.WriteAllLines(#"C:\Users\1\AppData\Roaming\MYDATA\hi.txt",
new string[] {somOne.ToString()});
I hope I'm getting your question correctly.
By this
// the Error line Is HERE \/
System.IO.File.WriteAllLines(#"C:\Users\1\AppData\Roaming\MYDATA\hi.txt", somOne);
you are saying you're getting an error on the above line?
You should've got a compile time error there. The 2nd parameter of WriteAllLines takes either an array or IEnumerable of strings.
Try adding this to your Persone class
public string[] Dump()
{
string[] tmp = new string[3];
tmp[0] = id.ToString();
tmp[1] = name;
tmp[2] = age.ToString();
return tmp;
}
then write to file using
System.IO.File.WriteAllLines(#"C:\Users\1\AppData\Roaming\MYDATA\hi.txt", someone.Dump());
Related
I need add objects to list, but I can't understand how to do it correctly.
Every new object I get from console.
How to fix it?
My try:
namespace ExampleCars
{
public class Car
{
public string name;
public int speed;
public Car(string name, int speed)
{
this.name = name;
this.speed = speed;
}
}
class Program
{
static void Main(string[] args)
{
string name;
int speed, elements;
List<Object> cars = new List<Object>();
elements = Convert.ToInt32(Console.ReadLine());
if (elements > 0)
{
for (int i = 0; i < n; i++)
{
name = Convert.ToString(Console.ReadLine());
speed = Convert.ToInt32(Console.ReadLine());
Car newCar = new Car(name, speed);
cars.Add(newCar);
}
}
foreach (var oneCar in cars)
Console.WriteLine(oneCar);
}
}
}
In console I get this (elements == 1):
ExampleCars.Car
First of all, it would be better to create a List of Cars, instead of list of Objects. So change this:
List<Object> cars = new List<Object>();
To this:
List<Car> cars = new List<Car>();
Also it would be great, if you use properties instead of fields. And finally as the solution for your question, and based on what you need to show in your last Console.Writeline method, you can override the ToString method. Your class should be something like this:
public class Car
{
public string Name { get; set; }
public int Speed { get; set; }
public Car(string name, int speed)
{
Name = name;
Speed = speed;
}
public override string ToString()
{
return $"Name = {Name}, Speed = {Speed} ";
}
}
And if you are using the older versions of C#:
return String.Format("Name = {0}, Speed = {1}", Name, Speed);
The $ is called String Interpolation and is available from C#6+. I have provided an equivalent of it using String.Format that is available in older versions of C#.
when you write your Car object in the console, Car.ToString method call in background.
Object.ToString is the major formatting method in the .NET Framework.
It converts an object to its string representation so that it is
suitable for display. Default implementations of the Object.ToString
method return the fully qualified name of the object's type.
Object.ToString Method
if you want to change default string presentation of your object, you have to override the method.
public class Car
{
public string name;
public int speed;
public Car(string name, int speed)
{
this.name = name;
this.speed = speed;
}
public override string ToString()
{
return $"{name} {speed}";
}
}
Console.WriteLine, is responsible of printing text.
In case of Console.WriteLine(string) is actually returns the string value;
In any other case, it tries to convert the value into a string by invoking the instance object .ToString() method.
Any type in C# inherits from System.Object, and thus, it has the .ToString() method.
By using Inheritance, many types override the actual inherited method and implement their perception of what their value should look like as a string.
This can be easily done, by using method overriding and apply your own logic.
Example taken from MSDN
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public override string ToString()
{
return "Person: " + Name + " " + Age;
}
}
Test code
Person person = new Person { Name = "John", Age = 12 };
Console.WriteLine(person);
// Output:
// Person: John 12
So you may ask, why do i get ExampleCars.Car ? you're getting it, because you didn't implement your own representation of the object .ToString method. Thus, the System.Object implementation is to actually return the instance type as string, which is exactly what you're getting.
System.Object.ToString() Source code.
public virtual String ToString()
{
return GetType().ToString();
}
System.Int32 implement by changing the value of 1 to "1"
While other type can implement their own. e.g: new DateTime(2018, 12, 31) can return "12/31/2018"
I am new to C# and I am creating a Form that is supposed to give the user the opportunity to enter name and age. Then, by submitting this information, there should be a summary(a new form) that shows what the user their input.
I finally got it working with the name, as it's a string and it's not a big deal, but I am stuck with the age.
I've tried casting, however, it does not work. I also looked at the documentation, but I do not find anything useful. Well, probably because I don't know where to look.
Anyway, I would strongly appreciate if someone give me an example for this.
Thanks in advance.
FormEnterDetails.cs
PersonStatic.LName = this.textBoxLastName.Text;
PersonStatic.Age = this.textBoxAge.Text;
DetailsHolder.cs
private string lName;
public string LName
{
get { return lName; }
set { lName = value; }
}
string age;
public String Age
{
get { return age; }
set { age = value; }
}
FormSummary.cs
private void FormSummary_Load(object sender, EventArgs e)
{
//we need to do this work on form load and not on creation
this.labelFirstNameSummary.Text = dh.FName;
this.labelLastNameSummary.Text = dh.LName;
this.labelAge.Text = Int32.Parse(dh.Age);
}
PersonStatic.cs
static string lName;
public static string LName
{
get { return PersonStatic.lName; }
set { PersonStatic.lName = value; }
}
static string age;
public static string Age
{
get { return PersonStatic.age;}
set { PersonStatic.age = value; }
}
I hope you want something like this
string ageString = ageInt.ToString();
Use the ToString() built-in function to convert anything to a string:
Int x=5;
String y;
y=x.ToString();
From the code you've posted, all places related to age appear to already be using string, not int (note that these are keywords that shorten the real type names, System.String and System.Int32). So you should be getting an error on this line:
this.labelAge.Text = Int32.Parse(dh.Age);
The Int32.Parse static method converts from a string to an int. (If you want to convert the other way, then as other answers have mentioned, you can call the ToString() instance method on your int.)
But in this case dh.Age, assuming dh is an instance of DetailsHolder, is already a string. And labelAge.Text, assuming labelAge is an instance of System.Windows.Forms.Label, is also a string. So you don't need to do any conversion:
this.labelAge.Text = dh.Age;
Suppose I have a list of Robot class [List< Robot> myList=new List< Robot>()]. Each Robot has a name and id depending on its colour. Now randomly pick values from the list and give an output of how many Robots of each colour are there on your list.
(N.B. Consider you have only 3 colored Robot[Yellow,green, red])
my code:
public class Test : MonoBehaviour
{
private void Start()
{
List<Robot> myList = new List<Robot>();
List<string> robotList = new List<string>();
robotList.Add("yellow");
robotList.Add("green");
robotList.Add("red");
int someNum = Random.Range(0, robotList.Count);
string robotNumber = robotList[someNum];
robotList.RemoveAt(someNum);
Robot robot;
int id = 0;
robot = new Robot(robotNumber, id);
Debug.Log(robot);
id++;
}
}
public class Robot
{
public string name;
public int id;
public Robot(string name, int id)
{
this.name = name;
this.id = id;
}
}
but this not work maybe.. actually I don't understand what actually my output is...
Not sure to really understand what you're asking for: if it's only about the meaning of the Debug.Log(robot); output, check for #Smartis answer as it answers it perfectly :)
Otherwise, I feel like you wanted to populate a List<Robot> with random picked names. In this case you need to use a loop: Start() method is only called once on start (as its name suggest). If you need to populate a list with random picked colors/names and then display how many of each colors/names are in the list you can do it as follow:
public class Test : MonoBehaviour
{
private void Start()
{
List<Robot> robotsList = new List<Robot>();
List<string> namesList = new List<string>();
namesList.Add("yellow");
namesList.Add("green");
namesList.Add("red");
PopulateRobotsList();
DisplayRobotsListContent();
}
private void PopulateRobotsList()
{
for(int id = 0; id < 100; id++)
{
string robotName = namesList[Random.Range(0, namesList.Count)];
robotsList.Add(new Robot(robotName, id));
//Debug.Log(robotsList[robotsList.Count - 1]);
}
}
private void DisplayRobotsListContent()
{
int[] robotsNamesCount = new int[namesList.Count];
for (int i = 0; i < robotsList.Count; i++)
{
robotsNamesCount[namesList.IndexOf(robotsList[i].name)] += 1;
}
for (int i = 0; i < namesList.Count; i++)
{
Debug.Log("Robot(s) named \"" + namesList[i] + "\" : " + robotsNamesCount[i]);
}
}
}
public class Robot
{
public string name;
public int id;
public Robot(string name, int id)
{
this.name = name;
this.id = id;
}
}
Please note I changed some variable names as I found it really hard to understand with the one you provided (ex: robotsList to store the potential colors/names of the robots is a weird choice of name :) ).
Hope this helps,
Your random pick works fine (even when your code is a little bit confusing). I guess your problem is, you don't understand the output of Debug.Log(robot);.
actually I don't understand what actually my output is... - OP
What does Debug.Log() print?
According to the Unity3D Documentation for this function will converted the given object to be to string representation for display. This means simply the return value of ToString() method on your Object will printed.
So let's have look at the Object.ToString() method and it's behavior in the MSDN Documentation.
Default implementations of the Object.ToString method return the fully qualified name of the object's type. - MSDN
So, your output in the Unity Log will be the Type Definition of your object.
Now, how to get useful information?
Just override the default ToString() method of your Robot class to something like this:
public class Robot
{
public string name;
public int id;
public Robot(string name, int id)
{
this.name = name;
this.id = id;
}
// Here start's the magic!
public override string ToString()
{
return string.Format("Robot -> Id:'{0}' Name:'{1}'", id, name);
}
}
public static int getInfo(string info)
{
string inputValue;
int infor;
Console.WriteLine("Information of the employee: {0}", info);
inputValue = Console.ReadLine();
infor = int.Parse(inputValue);
return infor;
}
In the above code, how can I get the name(string) and salary(int) of a person? Specifications are that I need to call the method twice for the information retrieval.
You can pass it separately or better if you create a class which holds of info and the salary
public static int getInfo(string info,int salary)
or create a class,
public class MyInfo
{
public int info { get; set; }
public int salary { get; set; }
}
and the method signature goes as,
public static int getInfo(MyInfo info)
If you want to return both string and int , better to change the method signature as of type class MyInfo
public static MyInfo getInfo(MyInfo info)
You could make it return a tuple with both values like this:
internal Tuple<int, string> GetBoth(string info)
{
string inputValue;
int infor;
Console.WriteLine("Information of the employee: {0}", info);
inputValue = Console.ReadLine();
infor = int.Parse(inputValue);
return new Tuple<int, string>( infor, inputValue );
}
internal void MethodImCallingItFrom()
{
var result = GetBoth( "something" );
int theInt = result.Item1;
string theString = result.Item2;
}
For returning multiple values from a method we can use Tuples or (DataType, DataType,..).
Tuples are readonly. As a result assigning values is possible only via constructor at the time of declaration.
Below example is using multiple data types as return type. Which is both read and write enabled.
public (string, int) Method()
{
(string, int) employee;
employee.Item1="test";
employee.Item2=40;
return employee;
}
You can call the above method in your main code, as shown below:
static void Main(string[] args)
{
(string name,int age) EmpDetails = new Program().Method();
string empName= EmpDetails.name;
int empAge = EmpDetails.age;
//Not possible with Tuple<string,int>
EmpDetails.name = "New Name";
EmpDetails.age = 41;
}
However, the best practice is to use class with properties, as mentioned in above answers.
public static void Main(string[] args)
{
string eName, totalSales;
double gPay, tots, fed, sec, ret, tdec,thome;
instructions();
eName = getInfo("Name");
totalSales = getInfo("TotalSales");
tots = double.Parse(totalSales);
gPay = totalGpay(tots);
}
public static string getInfo(string info)
{
string inputValue;
Console.WriteLine("Information of the employee: {0}", info);
inputValue = Console.ReadLine();
return inputValue;
}
This is what was required. Could have done with other tricks mentioned by you guys. Anyway thank you.
Why dont you just return a String array with a size of 2? at the first (array[0]) there is the string and at the second (array[0]) there is the int...
public static string[] GetInfo (string info)
I hope I understood your question right ^^
you need to create a person class and read name and salary
public class Person
{
public string Name {get; set;}
public decimal Salary {get; set;}
}
and your function will be:
public static Person getInfo(string info)
{
string inputName;
string inputSalary;
Console.WriteLine("Information of the employee: {0}", info);
Console.WriteLine("Name:");
inputName = Console.ReadLine();
Console.WriteLine("Salary:");
inputSalary = Console.ReadLine();
Person person = new Person();
person.Name = inputName;
person.Salary = int.Parse(inputSalary);
return person;
}
If you want one method to return different types of information, then I would use generics:
public static T GetInfo<T>(string name);
// This can be called as following:
string name = GetInfo<string>("name");
int salary = GetInfo<int>("salary");
There's one problem, though: Console.ReadLine returns a string, while our method could return any type. How can it convert a string to its 'target' type? You could check T and write custom logic for all types you want to support, but that's cumbersome and brittle. A better solution is to let the caller pass in a little function that knows how to transform a string into a specific type:
public static T GetInfo<T>(string name, Func<string, T> convert);
// This can be called as following:
string name = GetInfo<string>("name", s => s);
int salary = GetInfo<int>("salary", int.Parse);
Now how do you implement that method?
public static T GetInfo<T>(string name, Func<string, T> convert)
{
Console.WriteLine("Please enter " + name);
string input = Console.ReadLine();
return convert(input);
}
A few notes:
Type parameters are often just named T, but I find it useful to give them more descriptive names, such as TInfo.
The <string> and <int> parts can be left out in the second example, because the compiler has sufficient information to infer their types.
I've left our error handling to keep the examples short and simple. In production code, you'll want to come up with a strategy to handle invalid input, though.
I am using .Net 3.5 - I have a problem trying list box items to a text file. I am using this code:
if (lbselected.Items.Count != 0) {
string Path = Application.StartupPath + "\\ClientSelected_DCX.txt";
StreamWriter writer = new StreamWriter(Path);
int selectedDCXCount = System.Convert.ToInt32(lbselected.Items.Count);
int i = 0;
while (i != selectedDCXCount) {
string selectedDCXText = (string)(lbselected.Items[i]);
writer.WriteLine(selectedDCXText);
i++;
}
writer.Close();
writer.Dispose();
}
MessageBox.Show("Selected list has been saved", "Success", MessageBoxButtons.OK);
An error occurs for this line:
string selectedDCXText = (string)(lbselected.Items[i]);
The error is:
Unable to cast object of type 'SampleData' to type 'System.String'
please help me
Use string selectedDCXText = lbselected.Items[i].ToString();
You should override ToString method in class, which instances you want to write into file. Inside ToString method you should format correct output string:
class SampleData
{
public string Name
{
get;set;
}
public int Id
{
get;set;
}
public override string ToString()
{
return this.Name + this.Id;
}
}
And then use
string selectedDCXText = (string)(lbselected.Items[i].ToString());
Make sure that you have overridden the ToString method in your SampleData class like below:
public class SampleData
{
// This is just a sample property. you should replace it with your own properties.
public string Name { get; set; }
public override string ToString()
{
// concat all the properties you wish to return as the string representation of this object.
return Name;
}
}
Now instead of the following line,
string selectedDCXText = (string)(lbselected.Items[i]);
you should use:
string selectedDCXText = lbselected.Items[i].ToString();
Unless you have ToString method overridden in your class, the ToString method will only output class qualified name E.G. "Sample.SampleData"