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
Related
I'm trying to get and set a property using the following code.
But the when trying to print the property using Console,it returns an empty string.Why is the property not getting set?
using System;
public class Program
{
public static void Main()
{
myclass x=new myclass();
x.myproperty="test";
Console.WriteLine(x.myproperty);
}
class myclass{
string sample;
public string myproperty
{
get { return sample;}
set {sample=myproperty;}
}
}
}
In setter you should use value to assign new value to underlying field
use this instead
public string myproperty
{
get { return sample; }
set { sample = value; }
}
or in C#7
public string myproperty
{
get => sample;
set => sample = value;
}
Edit
As #bradbury9 mentioned, you can also use auto-implemented properties, of course this is the case if you don't want any other logic in getter and setter than just getting and setting the field, if this is the case you can use below snippet
public string myproperty { get; set; }
value keyword is important for setting the value. In Visual Studio you can use propfull + double tab to avoid such common mistakes. It will create full property through shortcuts.
Here is the solution
public static void Main()
{
myclass x = new myclass();
x.myproperty = "test";
Console.WriteLine(x.myproperty);
}
class myclass
{
string sample;
public string myproperty
{
get { return sample; }
set { sample = value; }
}
}
If you just want to return null instead of empty string. This works even when you deserialize your Json:
class myclass
{
string sample;
[JsonProperty("my_property")]
public string My_property
{
get { return sample; }
set { sample = string.IsNullOrEmpty(value) ? null : value; }
}
}
I have a few classes which have some primitive fields and I would like to create a generalized wrapper for them in order to access their fields. This wrapper should somehow contain a reference to the fields of my classes so that I can read/write the values of these fields. The idea is to create a genralized architecture for these classes so that I dont have to write code for each of them. The classes have fields which have a number in them which will be used as an Id to access the fields.
This is some example code that might shed some light on my requirement. What I want in the end is to change the value of some field in the object of Fancy1 class without accessing the object itself but through its wrapper.
class Fancy1
{
public double level1;
public bool isEnable1;
public double level2;
public bool isEnable2;
public double level3;
}
class Fancy2
{
public double level4;
public bool isEnable4;
public double level6;
public bool isEnable6;
public double level7;
}
class FieldWrapper
{
public int id { get; set; }
public object level { get; set; }
public object isEnabled { get; set; }
public FieldWrapper(int id, object level, object isEnabled)
{
this.id = id;
this.level = level;
this.isEnabled = isEnabled;
}
}
class FancyWrapper
{
private Fancy scn;
public FancyWrapper(Fancy scn)
{
if (!(scn is Fancy))
throw new ArgumentException(scn.GetType().FullName + " is not a supported type!");
this.scn = scn;
}
private Dictionary<int, FieldWrapper> fieldLut = new Dictionary<int, FieldWrapper>();
private List<FieldWrapper> _fields { get { return fieldLut.Values.ToList(); } }
public List<FieldWrapper> fields
{
get
{
if (_fields.Count == 0)
{
foreach (System.Reflection.FieldInfo fieldInfo in scn.GetType().GetFields())
{
if (fieldInfo.FieldType == typeof(double))
{
int satId = getIdNr(fieldInfo.Name);
fieldLut.Add(satId, new FieldWrapper(satId, fieldInfo.GetValue(scn), true));
}
}
foreach (System.Reflection.FieldInfo fieldInfo in scn.GetType().GetFields())
{
if (fieldInfo.FieldType == typeof(bool))
{
int satId = getIdNr(fieldInfo.Name);
fieldLut[satId].isEnabled = fieldInfo.GetValue(scn);
}
}
}
return _fields;
}
}
private int getIdNr(string name)
{
System.Text.RegularExpressions.Match m = System.Text.RegularExpressions.Regex.Match(name, #"\d+");
return Int32.Parse(m.Value);
}
}
class Program
{
static void Main(string[] args)
{
Fancy1 fancy = new Fancy1();
fancy.level1 = 1;
fancy.isEnable1 = true;
fancy.level2 = 2;
fancy.isEnable2 = false;
fancy.level3 = 3;
FancyWrapper wrapper = new FancyWrapper(fancy);
wrapper.fields[2].level = 10;
// fancy.level2 should somehow get the value I set via the wrapper
Console.WriteLine(fancy.level2);
Console.ReadLine();
}
}
EDIT: Fancy classes cannot be changed since they are part of an interface!
Depending on how many Fancy classes you are dealing with, you could create an adapter/facade class for each the expose a common interface. eg:
class Fancy1
{
public double level1;
public bool isEnable1;
public double level2;
public bool isEnable2;
public double level3;
}
public class FieldWrapper
{
private Action<double> _levelSetter;
private Func<double> _levelGetter;
private Action<bool> _enableSetter;
private Func<bool> _enableGetter;
public double level { get { return _levelGetter(); } set { _levelSetter(value); }}
public bool isEnabled { get { return _enableGetter(); } set { _enableSetter(value); }}
internal FieldWrapper(Func<double> levelGetter, Action<double> levelSetter, Func<bool> enableGetter, Action<bool> enableSetter)
{
_levelGetter = levelGetter;
_levelSetter = levelSetter;
_enableGetter = enableGetter;
_enableSetter = enableSetter;
}
}
abstract class FancyWrapper
{
public FieldWrapper[] Fields { get; protected set; }
}
class Fancy1Wrapper : FancyWrapper
{
private Fancy1 _fancy1;
public Fancy1Wrapper(Fancy1 fancy1)
{
_fancy1 = fancy1;
this.Fields = new[] { new FieldWrapper(() => fancy1.level1, level => _fancy1.level1 = level, () => _fancy1.isEnable1, enable => _fancy1.isEnable1 = enable),
new FieldWrapper(() => fancy1.level2, level => _fancy1.level2 = level, () => _fancy1.isEnable2, enable => _fancy1.isEnable2 = enable), };
}
}
Or you could invest 5 minutes learning data structures. Consider following example:
var levels = new Dictionary<int, bool>
{
{1, true},
{2, false}
};
if (levels[1])
{
//will run, because level 1 is true
}
if (levels[2])
{
//will not run, because level 2 is false
}
if (levels.ContainsKey(3) && levels[3])
{
//will not run, because dictionary does not contain entry for key 3
}
levels.Add(3, false);
if (levels.ContainsKey(3) && levels[3])
{
//will not run, because level 3 is false
}
levels[3] = true;
if (levels.ContainsKey(3) && levels[3])
{
//will run, because level 3 is true
}
That may seem like what you want, but it really isn't. It is extremely awkward on any number of levels. More specifically, pointers are generally rather "Un-C#-like" and having to know about these numbers defeats the point of having separate classes to begin with.
Think closely about what you want to accomplish. If you're having problems translating it into code, we're here to help. :)
Ok so I have a problem :/ first off Im using C#.. Next, in the section where you see
public int BaseValue()
{
get{return _basevalue;}
set{_basevalue value; }
}
I get 3 Errors
1) Unexpected symbol `{'
2)Unexpected symbol `{' in class, struct, or interface member declaration
and
3) Parsing Error
and frankly its pissing me off -_- so does anyone know what the problem may be?
public class BaseStats {
private int _basevalue; //base value of this stat
private int _buffvalue; //amount needed to buff the stat
private int _expToLevel; //amount needed to move to the next level
private float _LevelModifier; //the modifier applied to the exp needed to raise the skill
public BaseStats()
{
_basevalue = 0;
_buffvalue = 0;
_expToLevel = 100;
_LevelModifier = 1.1f;
}
//Basic Setters and Getters
public int BaseValue()
{
get{return _basevalue;}
set{_basevalue value; }
}
public int BuffValue()
{
get{return _buffvalue; }
set{_buffvalue value; }
}
public int ExpToLevel()
{
get{return _expToLevel; }
set{_expToLevel.value; }
}
public float LevelModifier()
{
get{return _levelModifier; }
set{_levelModifier.value; }
}
private int CalculateExpToLevel()
{
return (int)(_expToLevel * _levelModifier);
}
public void LevelUp()
{
_expToLevel = CalculateExpToLevel();
_baseValue++;
}
public int AdjustedValue()
{
return _baseValue + _buffValue;
}
}
Properties do not have parentheses. Eliminate the () and fix your setter on what you intend to be properties. Eliminate the get/set on what you intend to be methods.
// this is a property
public int Foo
{
get { return foo; }
set { foo = value; }
}
// this is a method
public decimal Bar()
{
// do something and return a decimal
}
And note, as of C# 3, if your property is a simple get/set operation, you can use auto-implemented properties and eliminate the explicit backing variable.
public int Foo { get; set; }
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:)
}
}
I want to create a property in C# that sets or returns an individual member of an array. Currently, I have this:
private string[] myProperty;
public string MyProperty[int idx]
{
get
{
if (myProperty == null)
myProperty = new String[2];
return myProperty[idx];
}
set
{
myProperty[idx] = value;
}
}
However, I get the following compile error:
Bad array declarator: To declare a managed array the rank specifier precedes the variable's identifier. To declare a fixed size buffer field, use the fixed keyword before the field type.
How about this: write a class that does one thing and one thing only: provide random access to elements of some underlying indexed collection. Give this class a this indexer.
For properties that you want to provide random access to, simply return an instance of this indexer class.
Trivial implementation:
public class Indexer<T>
{
private IList<T> _source;
public Indexer(IList<T> source)
{
_source = source;
}
public T this[int index]
{
get { return _source[index]; }
set { _source[index] = value; }
}
}
public static class IndexHelper
{
public static Indexer<T> GetIndexer<T>(this IList<T> indexedCollection)
{
// could cache this result for a performance improvement,
// if appropriate
return new Indexer<T>(indexedCollection);
}
}
Refactoring into your code:
private string[] myProperty;
public Indexer<string> MyProperty
{
get
{
return myProperty.GetIndexer();
}
}
This will allow you to have as many indexed properties as you want, without needing to expose those properties with the IList<T> interface.
You must use this as the property name for indexers.
C# allows only one indexed property per class, so you are forced to use this.
You can use it this way:
private string[] myProp;
public string[] MyProp
{
get
{
if (myProp == null)
{
myProp = new String[2];
}
return myProp;
}
set
{
myProp = value;
}
}
And it's possible to acces myProp[1] as MyProp[1] for Example
Exposing your array through a read-only property might cover your needs. Since you don't want to allow other code to assign the array as such, there is no need for a public setter:
private string[] myProperty;
public string[] MyProperty
{
get
{
if (myProperty == null)
{
myProperty = new String[2];
}
return myProperty;
}
}
Then you can write code as such:
theObject.MyProperty[1] = "some string";
...but you cannot replace the array itself:
theObject.MyProperty = new string[2]; // will not compile
An option is to recode it as follows:
private string[] myProperty = new string[2];
public string[] MyProperty
{
get
{
return myProperty;
}
set
{
myProperty = value;
}
}
It'll compile, but it does have its own set of issues (fxCop will yell about it, but it can lead you to other options).
You could do something like this:
class Indexers
{
private string[] _strings = new [] {"A","B"};
private int[] _ints = new[] { 1, 2 };
public string[] Strings
{
get{ return _strings;}
}
public int[] Ints
{
get{ return _ints;}
}
}
class Program
{
static void Main(string[] args)
{
Indexers indexers = new Indexers();
int a1 = indexers.Ints[0];
string a2 = indexers.Strings[0];
}
}
C# provides no built-in mechanism to create indexed properties. You can use a class-level indexer (using this[int index] notation), but nothing like this on a property level.
One option is to create a helper class with an indexer and use this class as the property type. See an example on MSDN.
First, in-field declaration avoids excess check:
private string[] myProperty = new string[2];
You can implement several indexers via overloading by input type:
public string this[int index]
{
get
{
return myProperty[index];
}
set
{
myProperty[index] = value;
}
}
public object this[object a, object b] // different input type(s) (and different return type)
{
get
{
// do other stuff
}
}
You need to use an indexer. It works a little differently. See example:
public class Node
{
public Node this[int offset]
{
get { return localList[offset]; }
}
}
Note: You are allowed only one indexer per class. The reason is that it is too confusing to the compiler as to the meaning, so you only are allowed one.
You can also do this:
private static int[] _widget = new int[Counter];
public static int [] Widget
{
get { return _widget; }
set { _widget = value; }
}
...
for (int i = 0; i < MyClass.Counter; i++)
{
MyClass.Widget[i] = i;
}
...
double _newWidget5 = MyClass.Widget[5];
// and so on...