using System;
using System.Collections.Generic;
using System.IO;
namespace _2._1
{
class Narys
{
public string Vardas { get; set; }
public string Pavarde { get; set; }
public double Pinigai { get; set; }
public Narys()
{
}
public Narys(string vardas, string pavarde, double pinigai)
{
Vardas = vardas;
Pavarde = pavarde;
Pinigai = pinigai;
}
List<Narys> DuomenuSkaitymas()
{
List<Narys> nariai = new List<Narys>();
string[] eilutes = File.ReadAllLines(#"nariai.txt");
foreach (string eilute in eilutes)
{
string[] duomenys = eilute.Split(' ');
string vardas = duomenys[0];
string pavarde = duomenys[1];
double pinigai = double.Parse(duomenys[2]);
Narys narys = new Narys(vardas, pavarde, pinigai);
nariai.Add(narys);
}
return nariai;
}
void DuomenuIrasymas(List<Narys> nariai)
{
string[] eilutes = new string[nariai.Count];
for (int i = 0; i < nariai.Count; i++)
{
eilutes[i] = String.Format("{0} {1} {2}", nariai[i].Vardas, nariai[i].Pavarde, nariai[i].Pinigai);
}
File.WriteAllLines(#"nariaiAts.txt", eilutes);
}
void DuomenuParodymas(List<Narys> nariai)
{
foreach (Narys narys in nariai)
{
Console.WriteLine("Vardas: {0}\nPavarde: {1}\nPinigai: {2}", narys.Vardas, narys.Pavarde, narys.Pinigai);
}
}
}
class Program
{
static void Main(string[] args)
{
Program p = new Program();
List<Narys> nariai = p.DuomenuSkaitymas();
p.DuomenuIrasymas(nariai);
}
}
}
And why i'm getting those errors ?
I think it should work, but it isn't, so i guess you will be able to solve this sh*t. Also, i'm studying in university and i am doing this by example and it really should work. I think there should be enough info for you guys.
Just look at your code:
class Program
{
static void Main(string[] args)
{
Program p = new Program();
List<Narys> nariai = p.DuomenuSkaitymas();
p.DuomenuIrasymas(nariai);
}
}
You are declaring the class Program that contains only a static method. Then you instantiate that class in variable p. Then you are trying to access some DuomenuSkaitymas method of it. But it contains only a static method. So how should this work?
You probably wanted to instantiate class Narys in p instead of Program.
Just a pro tip: never use identifier names in your local language, even if it looks more understandable at first. Your code might well end in the hands of others who don't understand your language. Believe me, you will choose better identifiers if you want others to understand your code - and that will be valuable to you too.
Your class Program just contains the main() method, so the IDE informs you that Program does not contains DuomenuSkaitymas method.
That method (DuomenuSkaitymas) , is defined in the Nary's class, so probably you need to modify you main method to
class Program
{
static void Main(string[] args)
{
Narys p = new Narys();
List<Narys> nariai = p.DuomenuSkaitymas();
p.DuomenuIrasymas(nariai);
}
}
I didn't check what the program means itself just clarifying your CS1061, so if there is other problems try to look closely to the code and understand what it means. If any other issue non related to this CS1061 arises after that you could try to post a new question with your issues or ideas about it.
Related
i have fixed the question:
The code is working until it hit the MultyMethod it stop because i have tried to take the output from the SumMethod and do another calculation in the MultyMethod.
So my question is i have tried to use the same input from SumMethod in the MultyMethod but it does not work well i have used all the reference in my mind or i could think of but still it told me : the name "SumMethod" need a reference to call it or you forgetting to use a reference. So how i could use the same input from the SumMethod in the MultyMethod!!
using System;
namespace example
{
class Program
{
public int number1 { set; get; }
public int number2 { set; get; }
public int sum { set; get; }
public int multy { set; get; }
static void Main(string[] args)
{
var value = SumMethod();
var values = MultyMethod();
ResultMethod(value.number1, value.number2, value.sum, values.multy);
}
public static Program SumMethod()
{
var input = new Program();
int i = 0;
Console.WriteLine(" Please Enter your first number: ");
input.number1 = int.Parse(Console.ReadLine());
Console.WriteLine(" Please Enter your second number: ");
input.number2 = int.Parse(Console.ReadLine());
int[] arr = new int[] { input.number1, input.number2 };
do
{
input.sum += arr[i];
i++;
} while (i < 2);
return input;
}
public static Program MultyMethod()
{
var input = new Program();
// here is the issue i am trying to get the input from the previous method instead of asking the user to input the numbers again
// i have tried this
//input.number1 = new input.SumMethod();
// and also have tried to use this reference
//value.SumMethod(); // since the inputs store in this variable but it does not make since to call it this way ><
// i have also tried to use this way
//input.number1 = new SumMethod();
return input;
}
public static void ResultMethod(int number1, int number2, int sum, int multy)
{
Console.WriteLine(" The first number is: ");
Console.WriteLine(number1);
Console.WriteLine(" The second number is: ");
Console.WriteLine(number2);
Console.WriteLine(" The sum of the number is: ");
Console.WriteLine(sum);
Console.WriteLine(" The multiplication of the numbers is: ");
Console.WriteLine(multy);
}
}
}
Okay, your basic problem is that the variable input, which you wish to reference in MultyMethod, is internal to SumMethod. Therefore, MultyMethod can't access it.
You define another variable called input in MultyMethod, but that is NOT the same variable. It's a separate one, the scope of which is just MultyMethod, and can't be accessed outside of it.
So, how to do what you want. I hope you don't mind that I'm also going to make some suggestions about how you could better organize this code.
First, you could define input outside of SumMethod, as a class-level static variable. In that case, it could be accessed by both SumMethod and MultyMethod. The following is a short excerpt (with some lines removed to save space):
class Program
{
public int number1 { set; get; }
public int number2 { set; get; }
public int sum { set; get; }
public int multy { set; get; }
public static Program input = null;
static void Main(string[] args)
{
// etc.
}
public static Program SumMethod()
{
input = new Program();
// rest of the code
return input;
}
public static Program MultyMethod()
{
input = Program.input; // this is a static reference.
// desired multiplication code
return input;
}
Another option would be to parameterize MultyMethod so it takes a Program as a parameter, representing the input:
public static Program MultyMethod(Program input)
{
// You probably don't want to have the same variable have both your sum
// and your multiplication results.
Program newVar = new Program() { number1 = input.number1, number2 = input.number2 };
// Do things with newVar in place of "input"
return newVar;
}
Then you'd change Main to look like this:
var value = SumMethod();
var values = MultyMethod(value);
An even better version would separate getting the input from performing the summing. So you could do this:
static void Main(string[] args)
{
var input = GetInput();
var value = SumMethod(input);
var values = MultyMethod(input);
// do other things
}
Finally, the whole thing would be better if you had separate classes for all three of the following:
The program itself
The input parameters and results
The multiplication and sum methods
I am entering code into a list. However, when I try to iterate through the code in a method call, nothing is being returned.
The problem code is found in "public class iterating". I am not sure why it won't execute.
Basically, I would like someone to enter information. Once the information has been entered, I would then like the user to iterate through the list via a method call.
using System;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class Iterating
{
List<String> employees = new List<String>();
public void Test2()
{
//This is where I am trying to iterate//
for (int i = 0; i < employees.Count; i++)
{
Console.WriteLine(employees[i]);
}
}
}
public class Testing
{
public void Test1()
{
while (true)
{
List<String> employees = new List<String>();
Regex regex = new Regex(#"((.{5})-\d{2,5}-\d{2,5})|(#.*.com)");
Console.WriteLine("Please enter an e-mail");
string input = Console.ReadLine();
if(string.Equals(input, "quit", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("You have quit the program");
break;
}
else if (match.Success)
{
Console.WriteLine(match.Value);
employees.Add(match.Value);
}
}
}
}
public class Program
{
public static void Main()
{
Testing T1 = new Testing();
T1.Test1();
Iterating I1 = new Iterating();
I1.Test2();
}
}
You don't get any output since
Every loop in the collection stage uses a new employees list.
Your two classes do not share the same employees list - they each have their own separate list.
If you want the iterating class to print the contents of a list, you need to pass it the list in question.
A partial example:
public class Program {
public static void Main() {
List<String> employees = new List<String>();
Testing T1 = new Testing();
T1.Test1(employees);
Iterating I1 = new Iterating();
I1.Test2(employees);
}
}
You would modify your test methods to use the passed list rather than create new ones
public class Iterating {
List<String> employees = new List<String>();
public void Test2()
{
//This is where I am trying to iterate//
for (int i = 0; i < employees.Count; i++)
{
Console.WriteLine(employees[i]);
}
}
}
employees is always empty since this doesn't have anything to do with Testing.employees you might want to remove it and pass the list into Test2 or into the constructor.
Also, Testing.employees should be outside the while look
You can redesign your class like this
public class Iterating
{
public void Test2(List<String> employees)
{
//This is where I am trying to iterate//
for (int i = 0; i < employees.Count; i++)
{
Console.WriteLine(employees[i]);
}
}
}
public class Testing
{
public List<String> Test1()
{
List<String> employees = new List<String>();//this should be outside the while loop
while (true)
{
Regex regex = new Regex(#"((.{5})-\d{2,5}-\d{2,5})|(#.*.com)");
Console.WriteLine("Please enter an e-mail");
string input = Console.ReadLine();
if(string.Equals(input, "quit", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("You have quit the program");
break;
}
else if (match.Success)
{
Console.WriteLine(match.Value);//where is the match var
employees.Add(match.Value);//where is the match var
}
}
return employees;
}
}
public class Program
{
public static void Main()
{
Testing T1 = new Testing();
var employees = T1.Test1();
Iterating I1 = new Iterating();
I1.Test2(employees);
}
}
Maybe this is real simple or breaking all the rules or maybe I just dont know what its called so I cant find it.
Anyway, I want to be able to replace an entire object on the heap. I've added a small code sample to show what I want to do, and a way of doing it, but I just want to know if there is a more elegant way?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BasicObjectTest
{
class Program
{
static void Main(string[] args)
{
List<Test> testList = new List<Test>
{
new Test {Value=1,NiceString="First" },
new Test {Value=2,NiceString="Second" },
new Test {Value=3,NiceString="Third" }
};
var replacementTestClass = new Test { Value = 2, NiceString = "NEW" };
EasyWay(testList, replacementTestClass);
var correctTestClass = testList.FirstOrDefault(x => x.Value == 2);
Console.WriteLine(correctTestClass.NiceString); //Expecting "Forth"
Console.ReadLine();
HardWay(testList, replacementTestClass);
correctTestClass = testList.FirstOrDefault(x => x.Value == 2);
Console.WriteLine(correctTestClass.NiceString);
Console.ReadLine();
}
private static void HardWay(List<Test> testList, Test replacementTestClass)
{
//This will work!
var secondTestClass = testList.FirstOrDefault(x => x.Value == 2);
CopyPropertiesUsingPropertyInfo(secondTestClass, replacementTestClass);
}
private static void CopyPropertiesUsingPropertyInfo(Test secondTestClass, Test replacementTestClass)
{
foreach(var pi in secondTestClass.GetType().GetProperties())
{
pi.SetValue(secondTestClass, pi.GetValue(replacementTestClass, null));
}
}
private static void EasyWay(List<Test> testList, Test replacementTestClass)
{
//This wont work, but I want it to!
var secondTestClass = testList.FirstOrDefault(x => x.Value == 2);
secondTestClass = replacementTestClass;
}
}
}
and my Test object
class Test
{
public int Value { get; set; }
public string NiceString { get; set; }
}
There must be a more elegant way of doing this?
I know why the first alternative does not work: I just change the object reference for that variable.
Update:
Using this thinking I understood it for a long time I tested this now thinking it would work, but the test fails. Why? Didnt I replace the object so that every object using it should use the new object? See complete code below
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var main = new Main { Property = 1 };
var dependent = new Dependent(main);
void ChangeRef(ref Main Oldmain, Main newMain)
{
Oldmain = newMain;
}
ChangeRef(ref main, new Main { Property = 5 });
Assert.AreEqual(5,dependent.Main.Property);
}
}
public class Main
{
public int Property { get; set; }
}
public class Dependent
{
public Dependent(Main main)
{
Main = main;
}
public Main Main { get; set; }
}
There must be a more elegant way of doing this?
There is one basic thing you're missing. When you search for the object in the list, and one is found, you get back a copy of the reference pointing to that object. This means that when you alter it, you're only altering the copy. The original reference in the list is still pointing to that same old object instance.
but what if I didnt have a list. I just had the object reference in a
variable?
Then you could use the ref keyword to pass the reference type by reference:
public static void Main(string[] args)
{
var test = new Test { Value = 1, NiceString = "First" };
var newTest = new Test { Value = 2, NiceString = "AlteredTest!" };
UpdateTest(ref test, newTest);
Console.WriteLine(test.NiceString); // "AlteredTest!"
}
public static void UpdateTest(ref Test originalTest, Test other)
{
originalTest = other;
}
An alternative way to approach this is with the proverbial "extra level of indirection".
Instead of storing the objects in the list, you store wrapper objects instead. The wrapper object provides an "Item" field which points to the actual object. Then you can update the "Item" field to point it at the new object.
A simple generic wrapper class could look like this:
class Wrapper<T>
{
public T Item;
public Wrapper(T item)
{
Item = item;
}
public static implicit operator Wrapper<T>(T item)
{
return new Wrapper<T>(item);
}
}
Then you could use it like so:
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication2
{
class Test
{
public int Value { get; set; }
public string NiceString { get; set; }
}
class Wrapper<T>
{
public T Item;
public Wrapper(T item)
{
Item = item;
}
public static implicit operator Wrapper<T>(T item)
{
return new Wrapper<T>(item);
}
}
class Program
{
static void Main(string[] args)
{
var testList = new List<Wrapper<Test>>
{
new Test {Value = 1, NiceString = "First"},
new Test {Value = 2, NiceString = "Second"},
new Test {Value = 3, NiceString = "Third"}
};
var replacementTestClass = new Test { Value = 2, NiceString = "NEW" };
EasyWay(testList, replacementTestClass);
var correctTestClass = testList.FirstOrDefault(x => x.Item.Value == 2);
Console.WriteLine(correctTestClass.Item.NiceString); //Expecting "New"
Console.ReadLine();
}
private static void EasyWay(List<Wrapper<Test>> testList, Test replacementTestClass)
{
var secondTestClass = testList.FirstOrDefault(x => x.Item.Value == 2);
secondTestClass.Item = replacementTestClass;
}
}
}
with my code, I'm supposed to be able to call a question from my file at random and not reuse that question again.
But for some reason I'm stuck in the while loop and after a few hours of searching I still can't see why, so I hope you guys can help me out.
(he gets stuck after he generated 8 questions)
Code (for the generatequestion one, if you need more I can paste it but I hope this gives enough information):
lineCount = File.ReadLines(pad).Count();
questions = new string[lineCount, 2];
public string GenerateQuestion(int total)
{
if (total <= 10)
{
Random ran = new Random();
questionNumber = ran.Next(lineCount);
while (previousQuestions.Contains(questionNumber))
{
questionNumber = ran.Next(lineCount);
}
}
previousQuestions[questionCount] = questionNumber;
questionCount++;
return questions[questionNumber, 0];
}
You could make a method to return the lines in the file in random order.
public string[] GetQuestionsInRandomOrder()
{
var lines = File.ReadAllLines("test.txt");
var rnd = new Random();
lines = lines.OrderBy(line => rnd.Next()).ToArray();
return lines;
}
Then as you use the questions you can remove them from the array.
var isRemoved = Array.remove(array, item);
https://msdn.microsoft.com/en-us/library/vstudio/bb397721%28v=vs.100%29.aspx
This is easier that what I had before and will give greater control. I would create a class for this and this example is a starting point. You can add more functionality as you go along. By having a class to do all this work you can add methods to do additional features later on without having to rewrite code.
public class Logic
{
public List<string> AllQuestionsInRandomOrder { get; set; }
public List<string> QuestionsThatHaveBeenRemoved { get; set; }
public Logic()
{
QuestionsThatHaveBeenRemoved = new List<string>();
AllQuestionsInRandomOrder = GetQuestionsInRandomOrder().ToList();
}
public string GetUnusedQuestion()
{
var question =
AllQuestionsInRandomOrder.FirstOrDefault(x => !QuestionsThatHaveBeenRemoved.Contains(x));
QuestionsThatHaveBeenRemoved.Add(question);
return question;
}
public IEnumerable<string> GetQuestionsInRandomOrder()
{
var lines = File.ReadAllLines("test.txt").ToList();
var rnd = new Random();
lines = lines.OrderBy(line => rnd.Next()).ToList();
return lines;
}
public void RemoveQuestion(List<string> questions, string questionToRemove)
{
questions.Remove(questionToRemove);
}
}
I would avoid using loops and break the problem into separate methods or functions. It will make it easier to debug. This implementation does not separate the questions and answers out, so you will need to add a method that returns a dictionary of the questions and answers.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
var questions = new Questions();
var firstQuestion = questions.GetUnusedQuestion();
Console.WriteLine(firstQuestion);
}
}
class Questions
{
public string FileName { get; set; }
public static List<string> AllQuestionsAndAnswersFromFile { get; set; }
public List<string> AllQuestionsInRandomOrder { get; set; }
public List<string> QuestionsThatHaveBeenRemoved { get; set; }
public Questions()
{
FileName = "text.txt";
QuestionsThatHaveBeenRemoved = new List<string>();
AllQuestionsAndAnswersFromFile = new List<string>();
ReadQuestionsFromFile();
AllQuestionsInRandomOrder = GetQuestionsInRandomOrder().ToList();
}
public string GetUnusedQuestion()
{
var question =
AllQuestionsInRandomOrder.FirstOrDefault(x => QuestionsThatHaveBeenRemoved.Contains(x));
QuestionsThatHaveBeenRemoved.Add(question);
return question;
}
private static IEnumerable<string> GetQuestionsInRandomOrder()
{
var lines = AllQuestionsAndAnswersFromFile;
var rnd = new Random();
lines = lines.OrderBy(line => rnd.Next()).ToList();
return lines;
}
public void RemoveQuestion(List<string> questions, string questionToRemove)
{
questions.Remove(questionToRemove);
}
public void ReadQuestionsFromFile()
{
using (var reader = new StreamReader(FileName, Encoding.Default))
{
var text = reader.ReadToEnd();
var lines = text.Split('=');
foreach (var s in lines)
{
AllQuestionsAndAnswersFromFile.Add(s);
}
}
}
}
}
When you run out of questions, let's see what
while (previousQuestions.Contains(questionNumber))
{
questionNumber = ran.Next(lineCount);
}
actually does:
Is questionNumber one of the questions we already asked?
Yes, get a new question number. (because we've asked all the questions)
Is questionNumber one of the questions we already asked?
yes, get a new question number. (because we've asked all the questions)
A solution in this case would be to shuffle your questions that you return, removing them as you grab them.
I saw an example on MSDN where it would let you specify the default value if nothing is returned. See below:
List<int> months = new List<int> { };
int firstMonth2 = months.DefaultIfEmpty(1).First();
Is it possible to use this functionality with an object? Example:
class object
{
int id;
string name;
}
code:
List<myObjec> objs = new List<myObjec> {};
string defaultName = objs.DefaultIfEmpty(/*something to define object in here*/).name;
UPDATE:
I was thinking I could do something like this:
List<myObjec> objs = new List<myObjec> {};
string defaultName = objs.DefaultIfEmpty(new myObjec(-1,"test")).name;
But haven't been able to. It should be noted that I am actually trying to use this method on an object defined in my DBML using LINQ-To-SQL. Not sure if that makes a difference in this case or not.
You need to pass an instantiated class as a parameter of the DefaultIfEmpty.
class Program
{
static void Main(string[] args)
{
var lTest = new List<Test>();
var s = lTest.DefaultIfEmpty(new Test() { i = 1, name = "testing" }).First().name;
Console.WriteLine(s);
Console.ReadLine();
}
}
public class Test
{
public int i { get; set; }
public string name { get; set; }
}
To add to it and make it a bit more elegant (IMO) add a default constructor:
class Program
{
static void Main(string[] args)
{
var lTest = new List<Test>();
var s = lTest.DefaultIfEmpty(new Test()).First().name;
Console.WriteLine(s);
Console.ReadLine();
}
}
public class Test
{
public int i { get; set; }
public string name { get; set; }
public Test() { i = 2; name = "testing2"; }
}
As per the MSDN page on this Extension Method you can do what you want:
http://msdn.microsoft.com/en-us/library/bb355419.aspx
Check the sample on this page for an example on how to use this with an object.
i must admit i am not too sure i understand your question, but i'll try to suggest using double question mark if the returned object might be null. Like so:
myList.FirstOrDefault() ?? new myObject();
You can create a default Object Like this:
Object o_Obj_Default = new Object();
o_Obj_Default.id = 3;
o_Obj_Default.name = "C";
And add it to your default value :
string defaultName = objs.DefaultIfEmpty(o_Obj_Default).First().name;
If your list "objs" is empty, the result will be "C"