How this way of defining properties is called - c#

public class TestClass
{
private Dictionary<string, int> _testDictionary = new Dictionary<string,int>();
private string _key;
public int this[string key]
{
get { return _testDictionary[key];}
set
{
if (_testDictionary.ContainsKey(key))
_testDictionary[key] = value;
else
_testDictionary.Add(key, value);
}
}
}
public class Program
{
static void Main(string[] args)
{
TestClass test = new TestClass();
test["T1"] = 1;
test["T2"] = 2;
Console.WriteLine(test["T1"]);
Console.WriteLine(test["T2"]);
}
}
So how this way of defining properties is called, I want to read more about that. Also is it possible to have same definition like this in other places, for an example in Methods etc.

Your implementation is right, you could add your desired IndexerName but you don't have to. It is better to add a guide from the getter in case the key is not found, and you return some default value.
Check out this enter link description here
public class TestClass
{
private Dictionary<string, int> _testDictionary = new Dictionary<string, int>();
// you do not need a private property to store the key
// private string _key;
[IndexerName("MyKeyItem")]
public int this[string key]
{
get
{
if (_testDictionary.ContainsKey(key))
{
return _testDictionary[key];
}
return int.MinValue;
}
set
{
if (_testDictionary.ContainsKey(key))
_testDictionary[key] = value;
else
_testDictionary.Add(key, value);
}
}
}

It's called an indexed property.

Related

Dictionary inherited from base class cannot be added to from derived class

I have an abstract class for POs.
public abstract class PO
{
public abstract Dictionary<string, object> InvalidFields { get; }
public abstract string PONumber { get; set; }
}
Which is inherited by two different types of PO: CPO and POR.
public class CPO
{
private string poNumber;
public override Dictionary<string, object> InvalidFields => new Dictionary<string, object>();
public override string PONumber
{
get
{
return poNumber;
}
set
{
if (!ValidatePONumber(value)) InvalidFields.Add("CPO Number", value);
poNumber = value;
}
}
}
When ValidatePONumber(value) returns false, it correctly executes InvalidFields.Add() but the dictionary is never actually added to. In the Locals window, a new variable is created named Namespace.PO.InvalidFields.get returned and I can see the new key that is added. However, this.InvalidFields has no values.
So it looks like the dict in the abstract base class PO is being created and added to instead of the derived class CPO.
Thanks to Klaus for pointing out the issue. I resolved by setting up a private invalidFields field and returning that with InvalidFields.get because what I was doing was returning a new Dictionary class with every get.
public class CPO : PO
{
private string poNumber;
private Dictionary<string, object> invalidFields = new Dictionary<string, object>();
public override Dictionary<string, object> InvalidFields { get => invalidFields; }
public override PONumber
{
get
{
return poNumber;
}
set
{
if (!ValidatePONumber(value)) InvalidFields.Add("CPO Number", value);
poNumber = value;
}
}
}
The code as you have given above does not even compile. You derived class is not actually inheriting from the abstract class (I am assuming it is a typo). Even after addition abstract class, the dictionary instantiation throws an error because it is a property definition and missing 'set' definition (InvalidFields is missing 'set' accessor definition.
Also, this sounds to be a duplicate of Overriding fields or properties in subclasses
I have tried this with minor modifications, please see the code below. Like #yransis says in comments, The InvalidFields is being treated as a 'get' property, returning new instance of dictionary every time it is executing the 'Add' step.
class DerivedCpo : AbstractPo
{
private string poNumber;
private Dictionary<string, object> invalidFieldsBackingField;
public override Dictionary<string, object> InvalidFields
{
get
{
return invalidFieldsBackingField;
}
set { this.invalidFieldsBackingField = value; }
}
public DerivedCpo()
{
this.InvalidFields = new Dictionary<string, object>();
}
public override string PoNumber
{
get { return poNumber;}
set
{
if(!ValidatePONumber((value)))
InvalidFields.Add("CPO Number", value);
poNumber = value;
}
}
private bool ValidatePONumber(string value)
{
if (string.IsNullOrEmpty(value))
{
return false;
}
if (value.Length > 5)
return false;
return true;
}
}
Main method calling this class -
static void Main(string[] args)
{
var po = new DerivedCpo();
po.PoNumber = "test1";
po.PoNumber = "thisistheinvalidfieldpo";
if (po.InvalidFields != null && po.InvalidFields.Count > 0)
{
Console.WriteLine(#"There are {0} fields in invalidFields collection", Convert.ToString(po.InvalidFields.Count) );
}
Console.WriteLine("Press any key to continue.");
Console.ReadKey();
}
In the code above I have added explicit backing field. It is being instantiated only once in the constructor. That way the contents of InvalidFields are persistent. In your code, you are returning a new instance of dictionary, essentially losing the data that was stored between two 'get' calls.

Hashtable-like data structure with extra info to identify the preferred/current item

Is there in C#, a Dictionary or Hashtable or similar structure, with attribute (like in XML) or extra piece of data to specify that one specific item in the Hashtable is the preferred/current one. I would like to do something like :
Hashtable myHashtable = new Hashtable();
myHashtable.Add(key1, item1);
myHashtable.Add(key2, item2, true); // true = specify this item2 as the preferred/current
myHashtable.Add(key3, item3);
Other than having this preferred/current information saved inside the items.
As for now, I am using my own structure as follows, but still did not check all corner cases :
public class HashtableWithCurrent : Hashtable
{
String _currentKey = String.Empty;
public void Add(object key, object value, bool current)
{
// TODO make sure key is a String
//
base.Add(key, value);
//
_currentKey = (String)key;
}
public override void Remove(object key)
{
base.Remove(key);
// key also
if (_currentKey == key)
ClearCurrentKey();
}
public String CurrentKey
{
get
{
return _currentKey;
}
}
public void ClearCurrentKey()
{
_currentKey = String.Empty; // via a function rather than a setter to avoid unwanted setting
}
}
You can write your own, but I think you don't need it. Just use one private field in a class where you use a Hashtable:
class MyClass
{
private object _currentKey;
private Hashtable _myHashtable = new Hashtable();
public void Method()
{
// ...
_myHashtable.Add(key1, item1);
_myHashtable.Add(key2, item2);
_currentKey = key2;
_myHashtable.Add(key3, item3);
}
}

Using loop to get value in different variable in a class C#

I have a class with a different variable like this:
namespace Model
{
public class Example
{
private double _var1;
private double _var2;
private double _var3;
private double _var4;
private double _var5;
public double Var1
{
get { return _var1; }
set { _var1 = value; }
}
public double Var2
{
get { return _var2; }
set { _var2 = value; }
}
public double Var3
{
get { return _var3; }
set { _var3 = value; }
}
public double Var4
{
get { return _var4; }
set { _var4 = value; }
}
public double Var5
{
get { return _var5; }
set { _var5 = value; }
}
}
}
A method will using this class to be a model and assign a value to every variable in it.
How to get all the value in different variable inside this class? Thank you.
EDIT
I'm using Hassan code and the code look like this:
foreach (PropertyInfo var in typeof(Example).GetProperties())
{
if (var.Name.Contains("Var"))
{
_dataTable.Rows.Add(_dateDailyBalance, var.GetValue(_justANormalModelOfExample, null));
}
}
but it returns all zero. the expected returns is some value. Why?
Add System.Reflection namespace:
For example setting 0.1 to each property.
Example obj = new Example();
Type type = obj.GetType();
PropertyInfo[] properties = type.GetProperties();
double d = 0.1;
foreach (PropertyInfo property in properties)
{
property.SetValue(obj, d, null);
}
As Hassan said, if you're dead set on using each as different variables, reflection would be the way to loop through the variables.
But if they're all doubles, why not array them? You could do this a number of ways...
namespace Model
{
public class Example : IEnumerable<double>
{
private double vars = new double[5];
protected double this[int ix]
{
get { return vars[ix]; }
set { vars[ix] = value; }
}
public IEnumerator<double> GetEnumerator()
{
return vars;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return ((IEnumerable<double>)this).GetEnumerator();
}
}
}
This allows you to index an instance of the class like an array.
because all of your properties are in same type, it is better to use indexer. here is an easy example of indexer, try to write it for your code. (i made this example because it is easy to understand)
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MyClass me = new MyClass();
//you can use me[index] = value for accessing the index of your indexer
for (int i = 0; i < 3; i++)
{
MessageBox.Show(me[i]);
}
}
}
class MyClass
{
string[] name = { "Ali", "Reza", "Ahmad" };
public string this[int index]
{
get { return name[index]; }
set { name[index] = value; }
}
}
please let me know if you have any problem with understanding the code. and you need to change
string[]
to
double[]
for your code.
for more info see:
http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx

foreach dictionary to check derived class

I have a base class Rules.cs. There are 2 derived classes RowRules.cs and ColumnRules.cs. I have another class Test.cs. This class has a Dictionary <int, Rules> which keeps adding the values. When I loop through the dictionary I need to know if the value is a RowRule or a ColumnRule. To better understand I have the code below.
Rules.cs
class Rules
{
private int m_timepointId = 0;
private int m_studyId = 0;
public int TimepointId
{
get { return m_timepointId; }
set { m_timepointId = value;}
}
public int StudyId
{
get { return m_studyId; }
set {m_studyId = value; }
}
}
RowRules.cs
class RowRules : Rules
{
private int m_row;
public int Row
{
get { return m_row; }
set { m_row = value; }
}
}
ColumnRules.cs
class ColumnRules: Rules
{
private int m_column;
public int Column
{
get { return m_column; }
set { m_column = value; }
}
}
In the main class I have
private Dictionary<int, Rules> m_testDictionary = new Dictionary<int, Rules>();
ColumnRules columnrules = new ColumnRules();
RowRules rowRules = new RowRules();
rowRules.Row = 1;
rowRules.StudyId = 1;
m_testDictionary.Add(1, rowRules);
columnRules.Column = 2;
columnRules.TimepointId = 2;
m_testDictionary.Add(2, columnRules);
foreach(.... in m_testDictionary)
{
//Need code here.
//if(... == RowRules)
{
}
}
Now, I need to know what value will go in the foreach loop. Also, I need to know whether that particular dictionary row is a RowRule or a ColumnRule. Hope I am clear with the question. Any help will be really appreciated.
There are a bunch of answers that are telling you to test the type using "is". That's fine, but in my opinion if you're switching off the type of an object, you're probably doing something wrong.
Typically, derived classes are used when you need additional and varied functionality from a base class. Moreover, ad-hoc polymorphism via virtual and abstract methods means that you can let the run-time figure out the type, leading to significantly cleaner code.
For example, in your case, you might want to make Rules an abstract class, with an abstract ApplyRule() method. Then, each subclass can implement the method, with the full knowledge of what it means to be a rule of that type:
public class Rules
{
private int m_timepointId = 0;
private int m_studyId = 0;
public int TimepointId
{
get { return m_timepointId; }
set { m_timepointId = value;}
}
public int StudyId
{
get { return m_studyId; }
set {m_studyId = value; }
}
// New method
public abstract void ApplyRule();
}
class RowRules : Rules
{
private int m_row;
public int Row
{
get { return m_row; }
set { m_row = value; }
}
public override void ApplyRule() { // Row specific implementation }
}
class ColumnRules : Rules
{
private int m_column;
public int Column
{
get { return m_column; }
set { m_column = value; }
}
public override void ApplyRule() { // Column specific implementation }
}
Now, your loop is just:
foreach(var kvp in m_testDictionary)
{
kvp.Value.ApplyRule();
}
This should work:
foreach(KeyValuePair<int, Rules> pair in m_testDictionary)
{
if(pair.Value is RowRule)
{
// do row rule stuff
}
if(pair.Value is ColumnRule)
{
// do row column rule stuff
}
}
Here is more information on the is keyword.
Try the following
foreach(var rule in in m_testDictionary.Values)
{
var rowRules = rule as RowRules;
if (rowRules != null) {
// It's a RowRules
continue;
}
var columnRules = rule as ColumnRules;
if (columnRules != null) {
// It's a ColumnRules
continue;
}
}
You can try this:
foreach(var key in m_testDictionary.Keys)
{
var value = m_testDictionary[key];
if(value is RowRules)
{
//test your code.....
}
}
does that code work? You have added the same key twice I believe. This is the code you wanted I believe:
foreach(int key in m_testDictionary.Keys)
{
RowRules row = m_testDictionary[key] as RowRules;
if(row !=null)
{
//code here:)
}
}

C# class indexer setting dictionary not property

I am trying to implement a string indexer for a C# class, but when you set a property the dictionary gets set and not the property. It is probably something simple that i am missing, i just can't see it.
objFiveProp temp = new objFiveProp();
temp["index1"] = 3;
sets the temp._items["index1"].value to 3.
Class:
public class objFiveProp
{
#region Properties
private Dictionary<string, int> _items;
public int this[string key]
{
get { return _items[key]; }
set { _items[key] = value; }
}
public int index1 { get; set; }
public int index2 { get; set; }
public int index3 { get; set; }
public int index4 { get; set; }
public int index5 { get; set; }
#endregion
#region Constructor
public objFiveProp()
{
index1 = 0;
index2 = 0;
index3 = 0;
index4 = 0;
index5 = 0;
_items = new Dictionary<string, int>();
_items.Add("index1", index1);
_items.Add("index2", index2);
_items.Add("index3", index3);
_items.Add("index4", index4);
_items.Add("index5", index5);
}
#endregion
}
That's how it works. The Dictionary contains a copy of the integers you use to set it up - not a reference to the properties.
I would tackle this by using something like:
public class objFiveProp
{
private Dictionary<string, int> _items;
public int this[string key]
{
get { return _items[key]; }
set { _items[key] = value; }
}
public int Index1
{
get { return this["index1"]; }
set { this["index1"] = value; }
}
public int Index2
{
get { return this["index2"]; }
set { this["index2"] = value; }
}
// ....
public objFiveProp()
{
_items = new Dictionary<string, int>();
_items.Add("index1", index1);
_items.Add("index2", index2);
_items.Add("index3", index3);
_items.Add("index4", index4);
_items.Add("index5", index5);
}
#endregion
This causes your properties to always pull the values stored in your dictionary, as well as save there, so there aren't two copies of the values.
This is because in index set method you are setting the value of dictionary item
public int this[string key]
{
get { return _items[key]; }
set { _items[key] = value; } //here you are setting the value of dictionary item not the property
}
Either, create separate property for index1, index2 and so on or in set method above add checks, a dirty solution though, to set the value of member variable depending on the value of key; Something like:
set {
_items[key] = value;
if(key == "index1")
index1 = value;
}
int is a value type, not a reference type. When you set a value in the _items, it won't set the property, even though you initially added it from the property.
From MSDN
Variables that are based on value types directly contain values.
Assigning one value type variable to another copies the contained
value. This differs from the assignment of reference type variables,
which copies a reference to the object but not the object itself.
If you really need to be able to access your data both from the indexer and the property, one of the simplest way would be to rewrite your properties thusly:
public int indexN
{
get { return _items["indexN"]; }
set { _items["indexN"] = value; }
}
Another way would be to use reflection in the indexer's setter:
public int this[string key]
{
get { return _items[key]; }
set
{
_items[key] = value;
PropertyInfo prop = this.GetType().GetProperty(key);
if (prop != null)
{
prop.SetValue(this, null);
}
}
}
Remember though, reflection is relatively very S-L-O-W.
There are other ways to accomplish what you're trying to do as well, but perhaps the best solution is to not do this at all. Pick the best interface to your class, whether that be the indexer or the properties, and stick with it. Your code will be more maintainable (you won't have to upkeep two public interfaces to your class's data) and more readable (other coders won't need to know that the indexer and the properties are the same thing). Cheers!

Categories