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!
}
}
}
Related
I have a static class (C#):
public static class PRRoles
{
public static Dictionary<int, string> Roles
{
get
{
return DAPRRoles.GetPRRoles();
//Dictionary<int, string> returnme = new Dictionary<int, string>();
//returnme = DAPRRoles.GetPRRoles();
//return returnme;
}
}
public static bool IsPRRole(RoleType RT)
{
return Roles.ContainsKey((int)RT);
}
}
and this is how I call:
if(PRRoles.IsPRRole(RoleType.Contracts))
Here is class DAPRRoles with the method defined:
public class DAPRRoles
{
public static Dictionary<int, string> GetPRRoles()
{
Dictionary<int, string> dicRoles = new Dictionary<int, string>();
try
{
DataTable PRRoles = new WFDataLayer().GetPRRoles();
foreach (DataRow r in PRRoles.Rows)
{
dicRoles.Add(int.Parse(r["roleid"].ToString()), r["description"].ToString());
}
}
catch (Exception ex)
{
WriteLog(String.Format("GetPRRoles() threw Exception"));
WriteLog(String.Format("Message: {0}", ex.Message));
throw new Exception("JacobsWF.DAPRRoles.GetPRRoles Exception : " + ex.ToString());
}
return dicRoles;
}
}
note that I must type the method name because intellisense does not show it.
This is the enum definition for RoleType above and it is defined outside of any class and is used successfully throughout the code.
public enum RoleType
{
Undefined = 0,
//Employee Types
Employee = 1,
JobManager = 2,
Delegate = 3,
JobManager2 = 4,
//Purchase Request Buyer Types
Buyer = 100,
BusinessAdmin = 101,
Contracts = 102,
Admin = 103,
//Purchase Request Workflow Types
[Description("Property Manager")]
PropertyAdmin = 104,
[Description("Contract Administrator")]
ContractAdmin = 105,
[Description("Office Director")]
OfficeDirector = 106,
[Description("Program Manager")]
ProgramManager = 107,
[Description("Financial Analyst")]
FinancialAnalyst = 108,
//Groups
ADGroup = 1000,
SharePointGroup = 2000,
// External
ExternalContact = 10000
}
IsPRRole is not visible to any other class, pages or methods and the application will not build if there are any calls to the method. Is this because the Roles Property of the class accesses data outside the code?
Is there an easy way to resolve this? Can I create a static method in the static class that would be visible?
One more note: There are multiple instances of calling static methods throughout the rest of the solution - which includes multiple projects - all compile and run successfully. This is the only one that is giving me this issue.
Thanks,
John
You call static methods using the class name. So, if I boil your code down to something that compiles. I've updated my repro so that it's closer to your code (by including a DAPRRoles class and a RoleType enum). You should be able to create a simple console or WinForms or WPF app, throw this code in, see it compile and step through it by calling PRRoles.IsPRRole(someInt); :
public static class PRRoles {
public static Dictionary<int, string> Roles {
get {
return DAPRRoles.GetPRRoles();
}
}
public static bool IsPRRole(int i){
return Roles.ContainsKey(i);
}
}
public class DAPRRoles {
public static Dictionary<int, string> GetPRRoles() {
Dictionary<int, string> dicRoles = new Dictionary<int, string>();
dicRoles.Add(1, "One");
dicRoles.Add(5, "five");
return dicRoles;
}
}
public enum RoleType {
Undefined = 0,
Employee = 1,
JobManager = 2,
Delegate = 3,
JobManager2 = 4,
}
I can call it (from somewhere else in my app) this way: PRRoles.IsPRRole(1); and see true returned, if I pass 2, I see false.
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 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])}");
}
}
}
I am trying to automap a dictionary to another without replacing existing values with null but just update them with the new ones if necessary. However i can't get it to work anyway.
Code :
class Klass
{
public Dictionary<string, string[]> Dictionary = new Dictionary<string, string[]>();
}
class Main
{
private Klass ex1 = new Klass();
public Main()
{
Mapper.CreateMap<Klass, Klass>().ForAllMembers(opt => opt.Condition(srs => !srs.IsSourceValueNull));
TestRun("1");
TestRun("2");
TestRun("3");
//EVERY CALL REPLACES THE OTHER HERE IDK WHY [OTHER MAPPER VALUES I MEAN]
}
public void TestRun(string text)
{
var ex2 = new Klass();
ex2.Dictionary = new Dictionary<string, string[]>
{
{text, new []{"1", "2... etc as provided"}}
};
Mapper.Map(ex2, ex1);
}
}
Can someone point me out to some C# code examples or provide some code, where a Dictionary has been used as a property for a Class.
The examples I have seen so far don't cover all the aspects viz how to declare the dictionary as property, add, remove, and retrieve the elements from the dictionary.
Here's a quick example
class Example {
private Dictionary<int,string> _map;
public Dictionary<int,string> Map { get { return _map; } }
public Example() { _map = new Dictionary<int,string>(); }
}
Some use cases
var e = new Example();
e.Map[42] = "The Answer";
sample code:
public class MyClass
{
public MyClass()
{
TheDictionary = new Dictionary<int, string>();
}
// private setter so no-one can change the dictionary itself
// so create it in the constructor
public IDictionary<int, string> TheDictionary { get; private set; }
}
sample usage:
MyClass mc = new MyClass();
mc.TheDictionary.Add(1, "one");
mc.TheDictionary.Add(2, "two");
mc.TheDictionary.Add(3, "three");
Console.WriteLine(mc.TheDictionary[2]);
EDIT
When you use C# version 6 or later, you can also use this:
public class MyClass
{
// you don't need a constructor for this feature
// no (public) setter so no-one can change the dictionary itself
// it is set when creating a new instance of MyClass
public IDictionary<int, string> TheDictionary { get; } = new Dictionary<int, string>();
}
You could also look into indexers. (official MSDN documentation here)
class MyClass
{
private Dictionary<string, string> data = new Dictionary<string, string>();
public MyClass()
{
data.Add("Turing, Alan", "Alan Mathison Turing, OBE, FRS (pronounced /ˈtjʊ(ə)rɪŋ/) (23 June, 1912 – 7 June, 1954) was a British mathematician, logician, cryptanalyst and computer scientist.")
//Courtesy of [Wikipedia][3]. Used without permission
}
public string this [string index]
{
get
{
return data[index];
}
}
}
Then, once you have populated the dictionary internally, you can access it's information by going
MyClass myExample = new MyClass();
string turingBio = myExample["Turing, Alan"];
EDIT
Obviously, this has to be used carefully, because MyClass is NOT a dictionary, and you cannot use any dictionary methods on it unless you implement them for the wrapper class. But indexers are a great tool in certain situations.
In order to ensure the encapsulation is correct and the dictionary cannot be updated outside the class using Add or the form ExampleDictionary[1]= "test", use IReadOnlyDictionary.
public class Example
{
private Dictionary<int, string> exampleDictionary;
public Example()
{
exampleDictionary = new Dictionary<int, string>();
}
public IReadOnlyDictionary<int, string> ExampleDictionary
{
get { return (IReadOnlyDictionary<int, string>)exampleDictionary; }
}
}
The following code will not work, which is not the case if IDictionary is used:
var example = new Example();
example.ExampleDictionary[1] = test;
Another example of using a dictionary as a static property with only the get accessor:
private static Dictionary <string, string> dict = new Dictionary <string,string>(){
{"Design Matrix", "Design Case"},
{"N/A", "Other"}
};
public static Dictionary <string, string> Dict
{
get { return dict}
}
This structure can be used to replace values.
An example...
public class Example
{
public Dictionary<Int32, String> DictionaryProperty
{
get; set;
}
public Example()
{
DictionaryProperty = new Dictionary<int, string>();
}
}
public class MainForm
{
public MainForm()
{
Example e = new Example();
e.DictionaryProperty.Add(1, "Hello");
e.DictionaryProperty.Remove(1);
}
}
Since .net 4.6 you can also define a Dictionary like this:
private Dictionary<string,int> Values => new Dictionary<string, int>()
{
{ "Value_1", 1},
{ "Value_2", 2},
{ "Value_3", 3},
};
It's called Expression-bodied members!
You mean like a property bag ?
http://www.codeproject.com/KB/recipes/propertybag.aspx