Goal: In my property setter, I need to sometimes multiply the added/subtracted/incremented value to another variable.
For example, if I do the following code:
MyProperty+=1;
MyProperty++;
MyProperty-=1;
In my setter, I need that 1 to be available so I can multiply it to my value:
int myField;
public int MyProperty
{
get
{
return myField;
}
set
{
int variable = variableThatContainsTheOne * otherVariable;
myField= variable;
}
}
I currently am implementing a separate function setter but that is sloppy. And cant use the built-in "value" because that will be simply the updated "myField".
My questions are:
(A) Is there not a way to get that 1 by some built in value like "value"?
(B) Is there a creative way that you know of where I can encapsulate this into the property setter?
(C) Any way to know whether someone tried to increase, decrease, or set the value? (Encapsulated within the setter or property scope)
Related
Can I make a property in c# class that has no field, but I still can check the value and set it only if match?
I mean something like this:
public int Num
{
get;
set if value > 0 && value < 100;
}
I know that I can do this:
private int num;
public int Num
{
get
{
return num;
}
set
{
if (value > 0 && value < 100)
num = value;
}
}
But I want to do it without using a field, and just using property.
Is it possible?
To be clear: btw; it's not that the property won't be set to that value, it's just a different way to look at your question.
You can use attributes, but you'll need a way to validate them. For instance; the Range attribute:
[Range(0,100, ErrorMessage = "Value for {0} must be between {1} and {2}.")]
public int Num {get; set;}
So, this is typically used in MVC or EF like applications where the attributes are being checked by that particular framework.
There is some more info about that subject here: https://msdn.microsoft.com/en-us/library/cc668215(v=vs.110).aspx
It can also work in MVVM WPF applications, but again, you'll need a framework for that.
btw; it's not that the property won't be set to that value, it's just a different way to look at your question.
So if your use case is actually how to restrict and easily apply some business rules on a view or data-model, this is an accepted method. If you keep it to your original question can I do a conditional set without an if and a field?, the answer is no.
Some more attributes can be found here.
I think the answer is no. You may want to see this one and this one to know why.
Fields are ordinary member variables or member instances of a class. Properties are an abstraction to get and set their values.
by doing the first block, you just break shorthand that already defined in C# and if you want to implement that idea, I think #Stefan proposed a good one.
I have the basics down with properties, but I don't see a real use for them. Doesn't it just return the value of an equation? I mean there is no point in using a property if you could just write down a simple equation for it.
For example:
int currentValue;
public int CurrentValue
{
get { return currentValue; }
set { currentValue = value; }
}
Is the same thing as just:
currentValue;
Another example:
int currentValue;
public int CurrentValue
{
get { return currentValue * 5; }
set { currentValue = value; }
}
Is the same thing as:
currentValue = currentValue * 5;
In your first example, Public Fields versus Automatic Properties is a good answer. Basically, you should use always properties instead of fields for non-private things. This lets you do things like modify the code later without breaking things, and make a private set. Properties can also do things like notify code when they're changed or provide default or calculated values easily. And you can use auto-properties to cut down on extraneous code:
public int CurrentValue { get; set; }
Your second example is not a good use of properties, since it breaks the assumptions of how properties work. E.g. if I set the property to 3 and no exception is thrown, I'd expect it to be 3 when I get it, not 15. currentValue = currentValue * 5;, which could make sense working with a field, property, or local variable, makes the value 5 times larger. Maybe you meant something like this:
int currentBackingValue;
public int CurrentValue
{
get { return currentBackingValue * 5; }
}
Without a set, this can work nicely, and without breaking any conventions and assumptions: CurrentValue is calculated based on currentBackingValue.
(as an aside, you should note that the getters and setters of a property are, in fact, methods, just used with a field-like syntax to replace something like Java's getX/setX standard)
Getters and setters properties are handy if you want to add some extra functionality to your code, centralizing your function so you can change it only in one place. You almost never know when you're going to have to change something, but you can prepare.
This, along with the concepts of encapsulation and information hiding, are basic OOP concepts but very important...
V E R Y I M P O R T A N T
Don't underestimate this tremendous power D:
Its so... powerful...
Properties are also used in a number of other .NET technologies, WPF doesn't work without them (with a PropertyChanged event invoke in the setter) and WCF uses them extensively in data contracts.
Especially relating to WPF, the power of properties is that both the "get" and "set" fields are functions and so can do lots of things besides just returning or setting the backing private member. This comes in handy more times than you may think.
Example property (for WPF)
public String UIDisplayedString
{
get { return _member; }
set
{
_member = value;
PropertyChanged(new PropertyChangedEventArgs("UIDisplayedString"));
}
I have a class which has a 2D jagged array declared in it's constructor, and in that class I have two methods called GetXY and SetXY, that modify said array.
However, I am unsure whether I should use these methods or in fact declare the grid as public, meaning there would be 2 ways of setting and reading values in the array, like this:
ProceduralGrid pg = new ProceduralGrid(10, 10);
pg.grid[0][0] = 2;
pg.SetXY(0, 0, 2);
Which one shall I use, and why?
Why not use
public T this[int x, int y]
{
get
{
return grid[x][y];
}
set
{
grid[x][y] = value;
}
}
Naturally check for valid x and y etc...
Use methods to access the array. Either SetXY or an indexer as suggested be Alessandro. That way, you can later change the implementation without changing your class interface.
It is best to use methods to set variables that are used inernally.
This way you can protect your inner object and are free to implement extra validation or modify the object as required.
This allows you to easily change the behaviour of that object later on.
Say I have my class, and I have the non-static variable
int x = 5;
After the code runs x is changed to something else, how can I get the value x started with using reflection?
Short answer: you can't.
If you implement some kind of custom transactional system, than it is possible. Out of the box: no luck.
And yes, the custom transactional system can be very simple: add another field or property that you use to 'remember' the initial value.
if i understand you correctly you want the initial value of the x.
for that you need another member or parameter to keep the first initializing of x. for example in your class:
int FirstX = -1;// or any other value you know ain't gonna come
bool firstInitial = true;
public int X
{
set
{
if(firstInitial)
{
FirstX = value;
firstInitial = false;
}
x = value
}
}
Now if you mean default value that is set at class level, you already know as it is constant other way would be creating an instance of the class for which you need default value.
ClassName className= new ClassName();
className.MyProp//This will always give default value.
new ClassName().MyProp //would also do.
If you want list of transactional values you need to implement it, reflection is not meant for that.
I get the following error in my code and I'm not sure why:
Warning - 'SummaryForm.m_difficulty' is never assigned to, and will always have its default value 0
Code
public partial class SummaryForm : Form
{
// Declares variables with the values pulled from the 'MainForm'
int iCorrectACount = MainForm.iCorrectACount;
int iCurrentQIndex = MainForm.iCurrentQIndex;
private Difficulty m_difficulty;
public SummaryForm()
{
InitializeComponent();
double modifier = 1.0;
if (m_difficulty == Difficulty.Easy) { modifier = 1.0; }
if (m_difficulty == Difficulty.Medium) { modifier = 1.5; }
if (m_difficulty == Difficulty.Hard) { modifier = 2; }
// Sets the labels using integer values
lblCorrectNum.Text = iCorrectACount.ToString();
lblWrongNum.Text = (iCurrentQIndex - iCorrectACount).ToString();
lblScoreTotal.Text = (iCorrectACount * modifier).ToString();
}
Maybe this has something to do with why lblScoreTotal.Text will not change to the value * modifier but will on another form?
The reason I asked this question here is because someone advised me to disable warning messages but I didn't think that was the appropriate solution?
Thanks.
The compiler is entirely correct: nothing is going to change your m_difficulty field, as far as you've shown. What do you expect to set that value? Did you actually mean to set it to something based on MainForm as per iCorrectACount and iCurrentQIndex?
How do you expect it would ever be anything other than whatever (Difficulty) 0 evaluates as?
It's pretty dodgy to be pulling initial values from a statically-accessed instance of a form, too, IMO. It would be much better if the constructor accepted initial values from whatever was constructing it.
m_difficulty is private, so it can't be accessed from outside your class, but you never assign it inside, so it will never change.
Therefore, it makes no real sense to compare it, as it will always be equal to 0.
You should always initialize a variable after you declared it.
private Difficulty m_difficulty = new Difficulty();
Something like that.
So you prevent it to be null (in this case you would get an exception).
The warning just tells you this.
It sounds to me like you're expecting m_difficulty to be bound to a dropdown selection on your user form. It is not. Even if it were, you would want to access the SelectedValue property instead of the object itself. Maybe this is what you're looking for.
Difficulty m_difficulty = (Difficulty)Enum.Parse(ddDifficulty.SelectedValue);