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.
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!
}
}
}
I want this method to work with any variable - i.e., passing a "Price" value to the method then getting the total price of all items.
private int GetTotalValue(int stat){
int total = 0;
foreach(Item i in Vendor.items){
totalStat += i.stat;
}
return total;
}
However, it has no way of knowing the name of the variable that I passed as the parameter, and thus no way of accessing it in other objects.
How would I tell the method what variable I'm passing, instead of just the value of it?
If you always want the sum of some property value you could encapsulate that logic into a method, e.g. GetVendorItemSum:
internal class Program
{
private static void Main(string[] args)
{
var items = new[] {
new Item {Price = 1},
new Item {Price = 2}
};
var vendor = new Vendor {Items = items};
var vendorSum = GetVendorItemsSum(vendor, x => x.Price);
}
private static int GetVendorItemsSum(Vendor vendor, Func<Item, int> func)
{
return vendor.Items.Sum(func);
}
}
public class Vendor
{
public IEnumerable<Item> Items;
}
public class Item
{
public int Price { get; set; }
}
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 would like an advice. My project have a lot of equals methods with different values, and i would like to do a single method that does the same.
The methods are this:
private void Enum1()
{
Console.WriteLine(Enum.GetValue(ENUM1.Code));
Console.WriteLine(Enum.GetValue(ENUM1.Info));
}
private void Enum2()
{
Console.WriteLine(Enum.GetValue(ENUM2.Code));
Console.WriteLine(Enum.GetValue(ENUM2.Info));
}
private void Enum3()
{
Console.WriteLine(Enum.GetValue(ENUM3.Code));
Console.WriteLine(Enum.GetValue(ENUM3.Info));
}
This is the enums:
public enum ENUM1
{
Code = 1,
Info = 3
}
public enum ENUM2
{
Code = 91,
Info = 4
}
public enum ENUM3
{
Code = 6,
Info = 27
}
There is only a way to create a method by inserting the input type of enum to use? maybe a similar solution of this:
private void General("ENUM1")
{
var type = ENUM1;
switch (p)
{
case "ENUM1":
type = ENUM1;
case "ENUM2":
type = ENUM2;
case "CASALINGHI":
type = ENUM3;
default:
type = ENUM1;
}
Console.WriteLine(Enum.GetValue(type.Code));
Console.WriteLine(Enum.GetValue(type.Info));
}
I think something like this is what you are looking for:
private void General<T>()
{
var values = Enum.GetValues(typeof(T));
foreach(var value in values)
Console.WriteLine(value);
}
General<Enum1>();
General<Enum2>();
General<Enum3>();
Or this, depending on how you want to use it:
private void General(Type enumType)
{
var values = Enum.GetValues(enumType);
foreach(var value in values)
Console.WriteLine(value);
}
General(typeof(Enum1));
General(typeof(Enum2));
General(typeof(Enum3));
Why do you keep using enums, when you can easily use classes? Read more about Object-Oriented programming.
Create a single class:
public class MyEnum
{
public int Code
{
get; set;
}
public int Info
{
get; set;
}
public string Display()
{
Console.WriteLine(this.Code);
Console.WriteLine(this.Info)
}
//
// This will keep your enums static, available from any method
//
private static List<MyEnum> _globals = new List<MyEnum();
public static List<MyEnum> Globals ()
{
if (this._globals.Count == 0)
{
this._globals.Add(new MyEnum(){ Code = 1, Info = 3 });
this._globals.Add(new MyEnum(){ Code = 91, Info = 4 });
this._globals.Add(new MyEnum(){ Code = 6, Info = 27 });
}
return this._globals;
}
}
After this you can easily print out all the enums with the following code:
foreach (MyEnum* en in MyEnum.Globals())
{
en.Display();
}
Please look into solutions similar to this one, since your enum's obviously represent some data.
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