Why is the stack count resetting? - c#

For some reason, when the loadStack() method finishes, it's count resets to 0. no idea why.
here's my method:
static Stack<string> Proxies = new Stack<string>();
private static void loadStack()
{
foreach (string s in File.ReadLines(pfile))
{
Proxies.Push(s);
Console.WriteLine(Proxies.Count());
}
}
and here's my main method:
static string pfile;
static void Main(string[] args)
{
pfile = Console.ReadLine();
loadStack();
}
It goes through the entire file fine, but once it finishes the last line, the count resets to 0.

Following code works perfectly AND even after loadStack method is finished, Main function prints "3" as expected. Here is the C# fiddle link for your reference.
public class Program
{
static Stack<string> Proxies = new Stack<string>();
static List<string> lst = new List<string>{"a","b","c"};
public static void Main()
{
loadStack();
Console.WriteLine(Proxies.Count);
}
private static void loadStack()
{
foreach (string s in lst)
{
Proxies.Push(s);
Console.WriteLine(Proxies.Count);
}
}
}

Related

How to call a non static method in the main?

class Program
{
static void Main(string[] args)
{
//I want to call the bird method here
}
public void bird(Program program)
{
birdSpeech();
}
public void birdSpeech()
{
Console.WriteLine("Chirp Chirp");
}
}
How do I call bird in the main, I also tried to call the method from a object of the class but that didn't work
Does it even make sense to do this (I try to avoid static methods as much as possible).
If a method can be made static without changing the code, you should make it static. To answer your question though, you can create an instance of Program in your Main function and call the non-static methods through it.
class Program
{
static void Main(string[] args)
{
var p = new Program();
p.bird();
}
public void bird()
{
birdSpeech();
}
public void birdSpeech()
{
Console.WriteLine("Chirp Chirp");
}
}
Could do something like this
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var p = new Program();
p.bird(p);
}
public void bird(Program program)
{
birdSpeech();
}
public void birdSpeech()
{
Console.WriteLine("Chirp Chirp");
}
}

Trying to stop a field callback from firing unexpectedly

I'm running the following code, and I'm expecting a different outcome.
According to my intent, I would not expect to encounter the firing of my callback function when setting a value.
I would only expect to see my callback fire when checking the value of my field and that field's criteria were met to fire the event.
Could somebody breathe some understanding into this for me?
using System.Collections;
public static class CollectionHandler {
private static List<string> _origFileList = new List<string>();
public static List<string> origFileList {
get {
if (_origFileList.Count < 1) {
//Fire a Callback Function Call Here
myTestCallback();
}
return _origFileList;
}
set {
_origFileList = value;
}
}
private static void myTestCallback() {
Console.WriteLine("origFileList - Is now empty");
}
}
CollectionHandler.origFileList.Add("Value 1");
CollectionHandler.origFileList.Add("Value 2");
CollectionHandler.origFileList.RemoveAt(1);
CollectionHandler.origFileList.RemoveAt(0);
//Output> origFileList - Is now empty
CollectionHandler.origFileList.Add("Test Value #1 - Should not fire the callback !!! But it does");
//Output> origFileList - Is now empty
CollectionHandler.origFileList.Add("Test Value #2 - Should not fire the callback --- And it doesn't");
To understand what's going on you have to modify your code a little bit:
void Main()
{
CollectionHandler.origFileList.Add("Value 1");
CollectionHandler.origFileList.Add("Value 2");
CollectionHandler.origFileList.RemoveAt(1);
CollectionHandler.origFileList.RemoveAt(0);
//Output> origFileList - Is now empty
CollectionHandler.origFileList.Add("Test Value #1 - Should not fire the callback !!! But it does");
//Output> origFileList - Is now empty
CollectionHandler.origFileList.Add("Test Value #2 - Should not fire the callback --- And it doesn't");
}
public static class CollectionHandler
{
private static List<string> _origFileList = new List<string>();
public static List<string> origFileList
{
get
{
myTestCallback(_origFileList);
if (_origFileList.Count < 1)
{
//Fire a Callback Function Call Here
myTestCallback(_origFileList.Count());
}
return _origFileList;
}
set
{
_origFileList = value;
}
}
private static void myTestCallback(object s)
{
Console.WriteLine(s.ToString());
Console.WriteLine("========");
}
private static void myTestCallback(List<string> s)
{
foreach (var str in s)
Console.WriteLine(str);
Console.WriteLine("========");
}
}
Now you will be able to see the content of the list every time a getter is called.
Basically when this line is executed:
CollectionHandler.origFileList.Add("Test Value #1 - Should not fire the callback !!! But it does");
the getter is called prior to the Add() method when the origFileList is actually empty, that why _origFileList.Count < 1 condition is satisfied.
As stated, the problem is in the moment the property is accessed. This is before the action on it has taken place.
To add an alternate solution, which was a bit too long as a comment: you can wrap whichever list is set inside something like a (System.ComponentModel)BindingList. The BindingList exposes events to detect changes made to it. (not if the original list itself is a basic list and it is changed by outside sources though).
Example:
public static class CollectionHandler {
private static BindingList<string> _origFileList;
public static IList<string> origFileList
{
get=> _origFileList;
set
{
if(value == null) throw new ArgumentNullException();
if(_origFileList != null)
_origFileList.ListChanged -= OnListChanged;
_origFileList = new BindingList<string>(value);
_origFileList.ListChanged += OnListChanged;
}
}
static void OnListChanged(object sender, ListChangedEventArgs e)
{
if(_origFileList.Count== 0)
myTestCallback();
}
static CollectionHandler()
{
origFileList = new List<string>();
}
private static void myTestCallback() {
Console.WriteLine("origFileList - Is now empty");
}
}
After removing the last item, the count is less than one, so the next time you access CollectionHandler.origFileList, the get function is executed and the condition around the callback is checked.
This is effectively the same code, but will illustrate what #ckuri is referring to:
CollectionHandler.origFileList.Add("Value 1");
CollectionHandler.origFileList.Add("Value 2");
CollectionHandler.origFileList.RemoveAt(1);
CollectionHandler.origFileList.RemoveAt(0);
var theList = CollectionHandler.origFileList; // myCallBack will be called as the "get" method is called here
theList.Add("Test Value #1 - Should not fire the callback !!! But it does"); // call back will not be called here
var theListAgain = CollectionHandler.origFileList; // the get method is called again, but the count == 1 so the callback is not called
theListAgain.Add("Test Value #2 - Should not fire the callback --- And it doesn't");
I wanted to post my implementation regarding this.
I know that there is a lot of improvement to be made on this code (eg. exposing delegates to subscribe to, etc...), but for the purposes of gaining simple control over the adding and removing of items from the list, I simply wrapped it up and defined my own Add / RemoveAt methods (per Bradley Uffner's Comment on my OP).
class Program {
static void Main(string[] args) {
CollectionHandler.origFileList.Add("Value 1");
CollectionHandler.origFileList.Add("Value 2");
CollectionHandler.origFileList.RemoveAt(1);
CollectionHandler.origFileList.RemoveAt(0);
CollectionHandler.origFileList.Add("Test Value #1");
CollectionHandler.origFileList.Add("Test Value #2");
Console.Read();
}
}
public static class CollectionHandler {
private static rrList _origFileList = new rrList();
public static rrList origFileList {
get {
return _origFileList;
}
set {
_origFileList = value;
}
}
}
public class rrList {
private List<string> _origFileList = new List<string>();
private void myTestCallback() {
Console.WriteLine("List Is now empty");
}
private void ListChanged() {
Console.WriteLine("List Size: " + _origFileList.Count);
}
public void RemoveAt(int i) {
_origFileList.RemoveAt(i);
checkList();
}
public void Add(string stringToAdd) {
_origFileList.Add(stringToAdd);
checkList();
}
private void checkList() {
if (_origFileList.Count == 0) {
myTestCallback();
} else {
ListChanged();
}
}
}

In C# , in Visual Studio, using a Console Application, is there a way to make methods in a class and call them in main program using readline?

In C# , in Visual Studio, using a Console Application, is there a way to make methods in a class and call them in main program using readline?
Aka, a way to choose which methods to open when the program is running.
Easiest way is a switch statement for <4 cases, and a Dictionary for 4 or more cases.
class Program
{
private static IDictionary<string, Action> MethodMappings = new Dictionary<string, Action> {
{"Method1", Method1},
{"Method2", Method2},
...
}
public static void Main(string[] args) {
var methodCall = Console.ReadLine();
if (!MethodMappings.ContainsKey(methodCall)) {
//unrecognized command
}
MethodMappings[methodCall].Invoke();
}
private static void Method1() { ... }
private static void Method2() { ... }
}
This is very much possible using Reflection. Here is sample code to help you out:
class Program
{
public static void Hello1()
{
Console.WriteLine("\nHello 1");
}
public static void Hello2()
{
Console.WriteLine("\nHello 2");
}
static void Main(string[] args)
{
while (true)
{
String method = Console.ReadLine();
Type methodType = typeof(Program);
MethodInfo voidMethodInfo = methodType.GetMethod(method);
voidMethodInfo.Invoke(method,null);
}
}
}
For more information you can visit here.

using a list across different methods in c#

I am reading a file into a list and then want a button to pull a random entry from the list. I can do this in VB but am fairly new to c#. I know I have to make the list public, but I'm getting increasingly frustrated.
The code below reads the file to a list and then a listbox.
namespace texttoarray
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int counter = 0;
string line;
var list = new List<string>();
var file = new StreamReader(#"list.txt");
while ((line = file.ReadLine()) != null)
{
list.Add(line);
counter++;
}
listBox2.DataSource = list;
var rnd = new Random();
}
}
}
If you want to process some information inside one method and use this processed information inside another method, you can:
pass the information as an argument to the second method
keep the information inside your class and use it inside any method
I'll assume the second approach for you, so you can do something like this:
static class Program
{
// list inside your class with the information you need
private static List<string> fileLines;
private static void Main(string[] args)
{
// call the method to read your file and create the list
FirstMethod();
// second method to get a random line, in this case, will return the string
var result = SecondMethod();
Console.WriteLine(result);
Console.ReadLine();
}
private static void FirstMethod()
{
// with this approach you can load one line per string inside your List<>
var yourFile = File.ReadAllLines("C:\\test.txt");
fileLines = new List<string>(yourFile);
}
private static string SecondMethod()
{
// random number starting with 0 and maximum to your list size
var rnd = new Random();
return fileLines[rnd.Next(0, fileLines.Count)];
}
}

detect when "control flow" exits class

Assume I have a code:
class Module1 {
public static void Main(string[] args) {
Module1.level1();
}
public static void level1() {
Module1.level2();
}
public static void level2() {
Module2.level1();
}
}
[DetectWhenFlowExitsClass] // <-- note aspect
class Module2 {
public static void level1() {
Module2.level2();
}
public static void level2() {
Module2.level3();
}
public static void level3() {
throw new SystemException("oops");
}
}
After calling Main() I get a stacktrace:
Unhandled Exception: System.SystemException: oops
at Test.Module2.level3()
at Test.Module2.level2()
at Test.Module2.level1()
at Test.Module1.level2()
at Test.Module1.level1()
at Test.Module1.Main(String[] args)
Question
How to write aspect which detects moment when "control flow" exits code of class Module2?
That is, when Test.Module2.level1() finishes its work [here, due to exception].
Exist any shortcuts for this in PostSharp?
The most basic way would be to use OnMethodBoundaryAspect, which allows you to handle the method entry and method exit advices. You will need to count number of method of each particular class on the stack and when this count goes from 1 to 0, the control is leaving methods of the aspected class.
Here is the sample aspect code:
[Serializable]
public class DetectWhenFlowExitsClass : OnMethodBoundaryAspect
{
[ThreadStatic] private static Dictionary<Type, int> stackCounters;
private Type declaringType;
public override bool CompileTimeValidate(MethodBase method)
{
declaringType = method.DeclaringType;
return true;
}
private void EnsureStackCounters()
{
if (stackCounters == null)
stackCounters = new Dictionary<Type, int>();
}
public override void OnEntry(MethodExecutionArgs args)
{
EnsureStackCounters();
int counter;
stackCounters.TryGetValue(declaringType, out counter);
stackCounters[declaringType] = ++counter;
}
public override void OnExit(MethodExecutionArgs args)
{
EnsureStackCounters();
int counter;
stackCounters.TryGetValue(declaringType, out counter);
stackCounters[declaringType] = --counter;
if (counter == 0)
Console.WriteLine("Control leaving class {0}", declaringType.Name);
}
}
You will probably need to tinker with this aspect implementation a bit, but it works in basic situations.

Categories