I have tried to use Inheritance but it did not arrear to work, furthermore I tried using Composition but with equally little succes. The individual arrays is read from a text-file, which makes it specific data. The code is as follows:
The generating code:
public static void ReadText(string[] args)
{
Dictionary<string, int[]> rows = new Dictionary<string, int[]>();
string[] lines = File.ReadAllLines("txt.txt");
int counter = 0;
foreach (string s in lines)
{
//Console.WriteLine(s);
string[] arr = s.Split(' ');
int[] array = new int[arr.Length];
for (int i = 0; i < arr.Length; i++)
{
array[i] = Convert.ToInt32(arr[i]);
}
string key = "M_array_" + counter++;
rows.Add(key, array);
//ShowArray(array);
}
foreach (string key in rows.Keys)
{
Console.WriteLine($"{key}: {String.Join(" ", rows[key])}");
}
Console.ReadLine();
}
How do I call M_array_1 , M_array_2 etc. in an other class? Usually then I call one varibel from another class I use inheritance:
Class_example CE = new Class_example();
Or Composition:
public class wheel{}
public class car : wheel{}
Make your dictionary static and accessible from other classes?
public class MyClass
{
public static Dictionary<string, int[]> Rows = new Dictionary<string, int[]>(); // initialize just in case
public static void ReadText(string[] args)
{
Rows = new Dictionary<string, int[]>();
string[] lines = File.ReadAllLines("txt.txt");
...
}
}
public class AnotherClass
{
public void DoSomething()
{
// Make sure you have done MyClass.ReadText(args) beforehands
// then you can call the int array
int[] m_array_1 = MyClass.Rows["M_array_1"];
int[] m_array_2 = MyClass.Rows["M_array_2"];
// or
foreach (string key in MyClass.Rows.Keys)
{
Console.WriteLine($"{key}: {String.Join(" ", rows[key])}");
}
}
}
Related
I have the below code, and I need to find how many, and all pairs, of dictionary, which however belongs in another namespace's method:
using sys = System;
using gen = System.Collections.Generic;
namespace xtra
{
class TestClass
{
public void Sing()
{
gen::Dictionary<string, int> dict = new gen::Dictionary<string, int>()
{
["A"] = 1,
["B"] = 2,
["C"] = 3
};
}
}
}
namespace ConsoleApp99
{
class Program
{
static void Main(string[] args)
{
xtra.TestClass Joe = new xtra.TestClass();
Joe.Sing();
foreach (string name in Joe.Keys) //error!
sys.Console.WriteLine($"{name} {dict[name]}"); //error!
}
}
}
So, the method Sing creates and populates a dictionary, but, upon instantiation in another namespace (in Main), I can create it, but, how do I count pairs and print their values?? I do understand that Joe is a method that makes the dictionary, but I have no clue to reference Joe's dictionary..
The dict property access modifier must be public in order to access him from another class.
Another approach is to expose only the dict property by encapsulating him and make Sing() method private.
class TestClass
{
private Dictionary<string, int> _dict;
public Dictionary<string, int> dict
{
get
{
if (_dict == null)
{
Sing();
}
return _dict;
}
set { _dict = value; }
}
private void Sing()
{
_dict = new Dictionary<string, int>()
{
["A"] = 1,
["B"] = 2,
["C"] = 3
};
}
}
class Program
{
static void Main(string[] args)
{
xtra.TestClass Joe = new xtra.TestClass();
foreach (string name in Joe.dict.Keys)
sys.Console.WriteLine($"{name} {Joe.dict[name]}");
Console.ReadLine();
}
}
You need to define this dictionary as public property inside of TestClass in order to have access to it from different class/namespace:
namespace xtra
{
class TestClass
{
public Dictionary<string, int> Dict { get; set; }
public void Sing()
{
Dict = new Dictionary<string, int>()
{
["A"] = 1,
["B"] = 2,
["C"] = 3
};
}
}
}
namespace ConsoleApp99
{
class Program
{
static void Main(string[] args)
{
xtra.TestClass Joe = new xtra.TestClass();
Joe.Sing();
foreach (string name in Joe.Dict.Keys) //error!
sys.Console.WriteLine($"{name} {Joe.Dict[name]}"); //error!
}
}
}
This question already has answers here:
Help someone new to C# variables
(5 answers)
Closed 2 years ago.
In my current application while I have been able to implement the required logic that I need I am really stuck when trying to take off the content from the main method and using it from a different method .
My code is as below,
class Program
{
const string path = #"filePath";
static void Main(string[] args)
{
setUpValues();
}
private static void setUpValues()
{
var Content = JsonConvert.DeserializeObject<deploy>(File.ReadAllText(path));
List<Variable> variables = Content.Variables.ToList();
Scopes Scope = Content.ScopeValues;
string Version = null;
List<string> ListOfSelectedItems= new List<string>();
List<string> TempListOfSelectedItems = new List<string>();
List<string> Channels = new List<string>();
foreach (var item in variables)
{
if (item.Name.Equals("version"))
{
Version = item.Value;
}
if (item.Name.Equals("Selected"))
{
TempListOfSelectedItems.Add(item.Value);
}
}
Console.WriteLine("Version " + Version);
Console.WriteLine();
string SelectedItems= TempListOfSelectedItems[0];
ListOfSelectedItems = SelectedItems.Split(',').ToList();
Console.WriteLine();
Console.WriteLine("Selected Modules");
Console.WriteLine();
foreach (var item in ListOfSelectedItems)
{
Console.WriteLine(item);
}
foreach (var item in Scope.Channels)
{
Channels.Add(item.Name);
}
}
}
I want to be able to access the variable string Version , the List of ListOfSelectedItems and the List of channels from outside this method .. I want to use these in another as well . So how can I make these globally accessible ?
Would really appreciate your help on this as I have been stuck here
In order to use variables outside a method, you should declare them as fields of a class. Like this:
class Program
{
const string path = #"filePath";
static deploy Content;
static string Version;
static List<string> ListOfSelectedItems;
static List<string> TempListOfSelectedItems;
static List<string> Channels;
// and others
static void Main(string[] args)
{
setUpValues();
}
private static void setUpValues()
{
Content = JsonConvert.DeserializeObject<deploy>(File.ReadAllText(path));
List<Variable> variables = Content.Variables.ToList();
Scopes Scope = Content.ScopeValues;
Version = null;
ListOfSelectedItems = new List<string>();
TempListOfSelectedItems = new List<string>();
Channels = new List<string>();
foreach (var item in variables)
{
if (item.Name.Equals("version"))
{
Version = item.Value;
}
if (item.Name.Equals("Selected"))
{
TempListOfSelectedItems.Add(item.Value);
}
}
Console.WriteLine("Version " + Version);
Console.WriteLine();
string SelectedItems = TempListOfSelectedItems[0];
ListOfSelectedItems = SelectedItems.Split(',').ToList();
Console.WriteLine();
Console.WriteLine("Selected Modules");
Console.WriteLine();
foreach (var item in ListOfSelectedItems)
{
Console.WriteLine(item);
}
foreach (var item in Scope.Channels)
{
Channels.Add(item.Name);
}
}
}
You have to declare those fields as static because they are used in a static method. After the setUpValues finishes running, you can use those fields inside the Main method as well.
Also, this is not related to the question, but the general code convention in C# is to start methods' names with an uppercase letter (so SetUpValues instead of setUpValues) and to start the local variables' names with a lowercase letter (selectedItems instead of SelectedItems). Obviously, it's ultimately up to you how to name things and which code convention to use.
Create a class with properties that you want to access from other places. Instantiate this class in setUpValues and return this.
public class TestClass
{
public TestClass()
{
this.ListOfSelectedItems = new List<string>();
}
public string Version { get; set; }
public List<string> ListOfSelectedItems { get; set; }
}
And then modify your Main method as:
var myObj = setUpValues();
And then Modify setUpValues to return this:
private static TestClass setUpValues()
{
var Content = JsonConvert.DeserializeObject<deploy>(File.ReadAllText(path));
List<Variable> variables = Content.Variables.ToList();
Scopes Scope = Content.ScopeValues;
string Version = null;
List<string> ListOfSelectedItems = new List<string>();
List<string> TempListOfSelectedItems = new List<string>();
List<string> Channels = new List<string>();
foreach (var item in variables)
{
if (item.Name.Equals("version"))
{
Version = item.Value;
}
if (item.Name.Equals("Selected"))
{
TempListOfSelectedItems.Add(item.Value);
}
}
var retObj = new TestClass();
Console.WriteLine("Version " + Version);
Console.WriteLine();
retObj.Version = Version;
string SelectedItems = TempListOfSelectedItems[0];
ListOfSelectedItems = SelectedItems.Split(',').ToList();
Console.WriteLine();
Console.WriteLine("Selected Modules");
Console.WriteLine();
foreach (var item in ListOfSelectedItems)
{
Console.WriteLine(item);
retObj.ListOfSelectedItems.Add(item);
}
foreach (var item in Scope.Channels)
{
Channels.Add(item.Name);
}
return retObj;
}
Re-written everything exactly as my program has it:
class DictionaryInitializer
{
public class DictionarySetup
{
public string theDescription { get; set; }
public string theClass { get; set; }
}
public class DictionaryInit
{
//IS_Revenues data
public Dictionary<int, DictionarySetup> accountRevenue = new Dictionary<int, DictionarySetup>()
{
{ 400000, new DictionarySetup {theDescription="Call", theClass="Revenues"}},
{ 400001, new DictionarySetup {theDescription="Bill", theClass="Revenues"}},
{ 495003, new DictionarySetup {theDescription="Revenue", theClass="Revenues"}}
};
public Dictionary<int, DictionarySetup> accountExpenses = new Dictionary<int, DictionarySetup>()
{
{790130, new DictionarySetup { theDescription="Currency Hedge", theClass="Other income/expense"}},
{805520, new DictionarySetup { theDescription="Int Income", theClass="Other income/expense"}}
};
}
On my mainform:
DictionaryInit theDictionary;
btnClick() {
theDictionary = new DictionaryInit();
//Some code to loop through a datagridview
//Somemore Code
foreach (var item in theDictionary.accountRevenue)
{
int theKey = item.Key;
if (theKey == keyCode)
{
DictionarySetup theValues = item.Value;
DGVMain.Rows[rowindex].Cells[3].Value = theValues.theDescription;
DGVMain.Rows[rowindex].Cells[11].Value = theValues.theClass;
DGVMain.Rows[rowindex].Cells[12].Value = "Sale of Services";
Recording(rowindex);
}
}
}
Current work in progress:
DictionarySetup theValue;
if (theDictionary.accountExpenses.TryGetValue(keyCode,out theValue.theDescription) //[5]-> Account Type
{
//Some code to write dictionary data to the data grid view.
I'm working on making the TryGetValue and Contains(value) dictionary functions to work for now.
My current error messages are as follows:
"a property or indexer may not be passed as an out or ref parameter" when attempting the trygetvalue
and finally when trying the extension method i'm trying to create:
"Inconsistent accessibility, Dictionary<int, DictionaryInitializer.DictionarySetup> is less accessible than the method DictionaryUse<int, DictionaryInitializer.DictionarySetup>"
You have to make your field public....
Dictionary<int, DictionarySetup> accountRevenue
should be
public Dictionary<int, DictionarySetup> accountRevenue
if you want to refer to it from outside the class..
This part seems to also be missing a variable name;
public void DictionaryUse (int code, int key, Dictionary)
should be
public void DictionaryUse (int code, int key, Dictionary<int, DictionarySetup> theDictionary)
But I agree with the other comments, you seem to be re-inventing the wheel, just use the existing Dictionary utility methods
I have adapted some code that generates a random state value (below)
public static string GenRandomState()
{
List<string> lst = new List<string>();
randomState = string.Empty;
lst.Add("Alabama");
lst.Add("Alaska");
lst.Add("Arizona");
...
randomState = lst.OrderBy(xx => rnd.Next()).First();
return randomState;
} // End GenRandomState
I would like to remove the randomization and, instead, have the method call the states in the same order (Top to Bottom) each time the method is called.
So, what I'd like to see is this: each iteration, a state value (starting at the top) will be retrieved. The execution will continue until all the state values have been called. I think a Foreach loop would be appropriate but I am not sure how best to implement.
Because you are leaving the loop and only selecting one state each call I would not use a foreach loop and instead keep a index variable and use that to choose which index you are going to use.
First, I would move the creation of the list outside of the function so it is only done once.
public class StateInfo
{
static StateInfo()
{
lst.Add("Alabama");
lst.Add("Alaska");
lst.Add("Arizona");
...
}
static readonly List<string> _lst = new List<string>();
static readonly object _listLock = new object();
static int _nextIndex = 0;
public static string GetNextState()
{
int i = 0;
lock(_listLock)
{
i = _nextIndex;
_nextIndex = (_nextIndex + 1) % _lst.Count;
}
return _lst[i];
}
}
You can change the function to return an IEnumerable.
static void Main(string[] args)
{
foreach (var s in GetStates())
{
Console.WriteLine(s);
}
}
public static IEnumerable<string> GetStates()
{
var lst = new List<string>();
lst.Add("Alabama");
lst.Add("Alaska");
lst.Add("Arizona");
...
return lst;
}
I would like to create an array of objects. Each object has it's own int array.
For each object I assign values to it's array ONLY with keys given by myself (example: li[i].V[10] = 1; li[i].V[50] = 10; )
Can someone tell me how to do that? Can I do that without using Lists?
The second case is analogical to first. I would like to know how to assign values of object's List
using setter.
I tried to do that by myself. Unfortunately My code crashed cuz I don't know how to set the dimension of V and Word:
class CFiles
{
//private int[] v=new int[5];//dont want to specify the dimention of array here
private int[] v;//vector of file
private List<string> words;
public CFiles()
{
words = Words;
v = new int[50];
v = V;
}
public int[] V { get; set; }
public List<string> Words { get; set; }
}
class Program
{
static void Main(string[] args)
{
CFiles[] li = new CFiles[2];
for(int i=0;i<li.Length;i++)
{
li[i]=new CFiles();
li[i].V[10] = 1;
li[i].V[50] = 10;
li[i].V[50] = 15;
li[i].Words.Add("a");
li[i].Words.Add("ab");
li[i].Words.Add("abc");
}
for (int i = 0; i < li.Length; i++)
{
for(int j=0;j<li[i].V.Length;j++)
{
Console.WriteLine(li[i].V[j]);
}
}
Console.WriteLine();
}
}
Your constructor isn't right and your properties aren't quite right. You might want something more like this:
class CFiles
{
//private int[] v=new int[5];//dont want to specify the dimention of array here
private int[] v;
public int[] V { get { return v; } set { v = value; } }
private List<string> words;
public List<string> Words { get { return words; } set { words = value; } }
public CFiles()
{
words = new List<string>();
v = new int[51]; //needs to be 51 if you are going to assign to index 50 below
}
}
Other than those issues, your code seems to do what you want. You have an array of objects where each object has its own int array (in addition to a string of strings).
Is that not what you want?