C# getter setter default value - c#

How do you set default value for setter getter? I want to do some operations while setting the setter.
public bool spin {
get { return this.spin; }
set {
if (value == false) this.spinBack = true;
this.spin = value;
}
}
private bool spinBack;
I tried this on Unity3D and got this error when trying to do so.
StackOverflowException: The requested operation caused a stack
overflow.
I tried just setting the getter and leave getter as default like so
public bool spin {
get;
set {
if (value == false) this.spinBack = true;
this.spin = value;
}
}
private bool spinBack;
but I get this error
'spin.get' must have a body because it is not marked abstract, extern,
or partial

The StackOverflowException is due to your this.spin = value; line which is recursively setting spin.
Use a backing field instead:
public bool Spin
{
get { return _spin; }
set {
if (value == false) this.spinBack = true;
_spin = value;
}
}
private bool _spin;
private bool spinBack;

Related

I have an int[] member in a class that reassings value to every instance of the class with each new declaration

I have a class for saving interactions in a game, when a person reacts takes values from the status of the game to create a new instance of this class, then send it, this is fine, the problem is when I try to get the value at the end of the level, then every instance of the class has the same value for that property with coincides with the last object declared of that class
public class reactionOrOmission
{
public bool reacted
{
get { return _reacted; }
set { _reacted = value; }
}
public float reactionTime
{
get { return _reactionTime; }
set { _reactionTime = value; }
}
public bool correct
{
get { return _correct; }
set { _correct = value; }
}
public int[] flagType
{
get { return _flagType; }
set { _flagType = value; }
}
public float generalTime
{
get { return _generalTime; }
set { _generalTime = value; }
}
public string focus
{
get
{
return _focus != null ? _focus : "non_focusable";
}
set { _focus = value; }
}
private bool _reacted;
private float _reactionTime;
private bool _correct;
private int[] _flagType;
private float _generalTime;
private string _focus;
public reactionOrOmission(bool Reacted, float ReactionTime, bool Correct, int[] FlagType, float GeneralTime)
{
reacted = Reacted;
reactionTime = ReactionTime;
correct = Correct;
flagType = FlagType;
generalTime = GeneralTime;
if (Tobii.Gaming.TobiiAPI.GetFocusedObject() == null)
{
focus = "non_focusable";
}
else
{
///nonimportant///
}
}
}
Thought it may have been something relating to an integer array but i have tried arrayList and list and the same happens.
I think your class is correct but you use incorrect instances or maybe incorrect usage after create instances...I ran your class and set 4 different instance , each instance has different values.
so your usage of class is incorrect!

Class which contains an instance of the same class

I have to create a class in C#, call it Class1. This class must contain an enum field, called Flag. Flag has 4 possible values, say A,B,C,D. An instance of Class1 can contain another instance of Class1 where the state of Flag is different from A.
My question is: how to formulate the condition that the state of Flag in the sub-instance must be different from A?
Mark your Class1 "subinstance" as private and make it accessible only through a property. In the property setter, check that the value which is set has the flag different from the one of the parent. Be careful, if the parent Class1 flag must always be different from the child, then you also have to add a check when setting the parent flag.
You could make the setter private and check it in the constructor, you also have to provide a private constructor for the inner instance. So basically an immutable class:
public enum Flag
{
A, B, C, D
}
public class Class1
{
private Class1 _Class1Inner;
public Class1 Class1Inner
{
get { return _Class1Inner; }
private set { _Class1Inner = value; }
}
private Flag _Flag;
public Flag Flag
{
get { return _Flag; }
private set { _Flag = value; }
}
// used only to create the inner instance
private Class1(Flag innerFlag)
{
this.Flag = innerFlag;
_Class1Inner = null; // or whatever
}
public Class1(Flag flag, Flag innerFlag)
{
if (innerFlag == Flag.A)
throw new ArgumentException("innerFlag must not be Flag.A!", "innerFlag");
this.Flag = flag;
this.Class1Inner= new Class1(innerFlag);
}
}
If you want this class to be mutable, so that you can change the Flag after creation, you have to remember whether it is an inner instance or not.
Therefore you need another field which you can set from the constructor:
public class Class1
{
private bool _isInnerInstance = false;
private Class1 _Class1Inner;
public Class1 Class1Inner
{
get { return _Class1Inner; }
private set { _Class1Inner= value; }
}
private Flag _Flag;
public Flag Flag
{
get { return _Flag; }
set
{
if (_isInnerInstance && value == Flag.A)
throw new ArgumentException("innerFlag must not be Flag.A!", "innerFlag");
_Flag = value;
}
}
private Class1(Flag innerFlag)
{
this.Flag = innerFlag;
_isInnerInstance = true;
_Class1Inner = null; // or whatever
}
public Class1(Flag flag, Flag innerFlag)
{
if (innerFlag == Flag.A)
throw new ArgumentException("innerFlag must not be Flag.A!", "innerFlag");
this.Flag = flag;
_Class1Inner = new Class1(innerFlag);
}
}
Now following is not allowed:
Class1 cls1 = new Class1(Flag.A, Flag.B);
cls1.Class1Inner.Flag = Flag.A; // throws an ArgumentException at runtime
Started as a comment, but a bit too detailed so moved to answer...
On first though then, I would say that Class1 needs a way of knowing it is a 'sub-instance', for example you could force a constructor that defines this:
private IsSub { get; set; }
public Class1(bool isSub)
{
IsSub = isSub;
}
which sets a property in the class. This property can be used to check if the Flag can have A or not. But you will need a way to validate when the flag is set. For that you could add a validation method that throws an error to the property setter:
private Flag myFlag;
public Flag MyFlag
{
get { return myFlag; }
set { ValidateFlag(value); myFlag = value; }
}
void ValidateFlag(Flag flag)
{
if(IsSub && flag == Flag.A)
throw new Exception("Invalid flag");
}
Finally, you need to decide when to set the sub-instance. If you only want to allow one level of subinstance (so child class won't have their own child instances) then you can do it in the default constructor like so:
public Class1 ChildClass { get; set; }
public Class1()
{
ChildClass = new Class1(true);
}
(You also will want to think about how the default values for the flag properties are going to be set, but that is your logic to decide on.)
Here is example usage:
Class1 myClass = new Class1();
myClass.MyFlag = Flag.A; // This is fine.
myClass.SubClass.MyFlag = Flag.A; // This will throw an exception.

C# swap in Designer

I have my Control.When I change the properties of the control. I get this:
this.myLabel1.BorderShadow = true;
this.myLabel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
And I need to get this:
this.myLabel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.myLabel1.BorderShadow = true;
How to do so is done automatically in Form.Desinger.cs ?
If you say Why?
private bool BorderShadow_ = false;
public bool BorderShadow
{
get
{
return BorderShadow_;
}
set
{
if (Border_Style_ == BorderStyle.FixedSingle)
{
BorderShadow_ = value;
}
else
{
throw new ArgumentOutOfRangeException("BorderShadow", "BorderShadow can be true if BorderStyle=FixedSingle");
}
}
}
You could look into the ISupportInitialize interface. It allows you to skip the validity check when initializing your controls. For example (adapted from one of my projects):
public class MyControl : Control, ISupportInitialize
{
private bool _created = true;
public void BeginInit()
{
_created = false;
}
public void EndInit()
{
_created = true;
//check all your properties here too
}
private bool BorderShadow_ = false;
public bool BorderShadow
{
get
{
return BorderShadow_;
}
set
{
BorderShadow_ = value;
if (_created && Border_Style_ != BorderStyle.FixedSingle)
throw new ArgumentOutOfRangeException();
}
}
}
If I remember correctly, the VS designer will automatically add calls to BeginInit and EndInit for you as well.
I think they will appears in the same order as they are defined. So you can override with new old setting:
public new BorderStyle BorderStyle
{
get {return base.BorderStyle;}
set {base.BorderStyle = value;}
}
and then declare your BorderShadow setting.
The designer will always order the properties alphabetically and this can't be changed.
The sense of a property is that it is side effect free and that it can be changed at any time in any order. This means that if you have multiple properties which representing some kind of complex state and not all combinations are making sense, this error should not be reported while switching the property itself.
So to accomplish these problems you have two possibilities:
Like #Andrew already mentioned implement ISupportInitialize and take care if you are within this state.
Within the property setter call a method that checks if all settings currently made are making sense and perform the desired action only in this case:
public class MyControl : Control
{
private bool _BorderShadow;
private BorderStyle _BorderStyle;
public bool BorderShadow
{
get { return _BorderShadow; }
set
{
if(_BorderShadow != value)
{
_BordeShadow = value;
ApplyBorderShadowIfNeeded();
}
}
}
public BorderStyle BorderStyle
{
get { return _BorderStyle; }
set
{
if(_BorderStyle != value)
{
_BorderStyle = value;
ApplyBorderShadowIfNeeded();
}
}
}
private void ApplyBorderShadowIfNeeded()
{
if(_BorderStyle == BorderStyle.FixedSingle
&& _BorderShadow)
{
// ToDo: Apply the shadow to the border.
}
}
}

C# pass property

I have a class UserPane l: Panel. I do so.
private bool AutoSize_ = true;
public bool AutoSize
{
get
{
return AutoSize_;
}
set
{
AutoSize_ = value;
}
}
But when I change Autosize_ still returns are always true. How to make that value correctly transmitted.
The Panel class already have a property AutoSize.
You define a new Property with the same name. Check your warnings, you must have the following :
warning CS0114: 'UserPanel.AutoSize' hides inherited member 'System.Windows.Forms.Panel.AutoSize'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
When you are calling the AutoSize property of UserPanel, you are in fact calling the property of the superclass Panel. So your field AutoSize_ will never get changed.
Act accordingly to the warning :
public class UserPanel : Panel
{
private bool AutoSize_ = true;
public override bool AutoSize
{
get
{
return AutoSize_;
}
set
{
AutoSize_ = value;
}
}
}
On a side note, why do you want to change the already working AutoSize functionnality? Are you sure this is what you need?
You need to override the property, because it is already defined in Panel.
public override bool AutoSize {
get {
return base.AutoSize;
}
set {
base.AutoSize = value;
}
}
Isn't the compiler giving you the warning over this?
If you are doing something like this.
public partial class myPanel : Panel
{
private bool AutoSize_ = true;
public bool AutoSize
{
get
{
return AutoSize_;
}
set
{
AutoSize_ = value;
}
}
}
You are hiding Panels AutoSize property. You should override this property. You can override it to return the base value (which actually does not do much).
public override bool AutoSize
{
get
{
return base.AutoSize;
}
set
{
base.AutoSize = value;
}
}
Or maybe you can do some custom work there.
public override bool AutoSize
{
get
{
//return custom value
}
set
{
//set some custom value
}
}
If you have that class
class P : Panel
{
bool AutoSize_ = true;
public bool AutoSize
{
get
{
return AutoSize_;
}
set
{
AutoSize_ = value;
}
}
}
And then you create an instance and change the value of AutoSize like this:
var p = new P();
p.AutoSize = true;
This should work fine (at least in my tests), the problem arise when you do something like this:
var p2 = (Panel)p;
p2.AutoSize = false; // this change the AutoSize property of the Panel not the property of the derived class P
If this isn't your case then no idea what happens.

how to prevent infinite property change

Lets say I have sales price, down payment amount, down payment percent and loan amount. When any of these properties are changed by the user the others need to be updated to reflect the new values. How do you deal with this type of infinite property change events?
When flow control is necessary across multiple attributes, I'll institute a flow control variable - a boolean - and in each property that's being changed, I'll add a test to see if I'm under flow control or not.
private bool controlledChange = false;
public property int MyVal1
{
set
{
_myVal1 = value;
if(!controlledChange)
{
controlledChange = true;
MyVal2 -= 1;
controlledChange = false;
}
}
}
public property int MyVal2
{
set
{
_myVal2 = value;
if(!controlledChange)
{
controlledChange = true;
MyVal1 += 1;
controlledChange = false;
}
}
}
This way whatever property is changed can initiate changes across the other properties, but when they get changed, they will no NOT to initiate their own set of changes in turn.
You should also look to make as many of those properties read only as possible, if they can have calculated results, so that you limit how the object can be changed.
THe easiest way is to only raise a change event if the property has really changed:
public decimal SalePrice {
get{
return salePrice;
}
set {
if (salePrice != value) {
salePrice = value; // putting as first statement prevents the setter
// to be entered again ...
RaiseSalePriceChange();
// Set other properties
}
}
}
I'm not sure I completely understand, since I don't know what you mean by 'infinite'
This may be a good use case for actually backing your properties with fields. That way, you can trigger events on Property sets, but internally set the fields one at a time without triggering N events.
class MyClass
{
private string m_Name;
private int m_SomeValue;
public string Name
{
get { return m_Name; }
set
{
if (value != m_Name)
{
m_Name = value;
m_SomeValue++;
// Raise Event
}
}
}
public int SomeValue
{
get { return m_SomeValue; }
set
{
if (m_SomeValue != value)
{
m_SomeValue = value;
// Raise Event
}
}
}
If INotifyPropertyChanged is really needed to notify external objects, so I would just centralise everything. Like this:
private double salesPrice;
private double downPaymentAmount;
private double downPaymentPercent;
private double loanAmount;
public double SalesPrice
{
get
{
return salesPrice;
}
set
{
if (salesPrice != value)
{
salesPrice = value;
// maybe you would rather use a RecalculateForSalePriceChanged() method
RecalculateDownPaymentAmount();
RecalculateDownPaymentPercent();
RecalculateLoanAmount();
propertiesChanged();
}
}
}
public double DownPaymentAmount
{
get
{
return downPaymentAmount;
}
set
{
if (downPaymentAmount != value)
{
downPaymentAmount = value;
// see above
RecalculateDownPaymentPercent();
RecalculateLoanAmount();
RecalculateSalesPrice();
propertiesChanged();
}
}
}
public double DownPaymentPercent
{
get
{
return downPaymentPercent;
}
set
{
if (downPaymentPercent != value)
{
downPaymentPercent = value;
// see above
RecalculateDownPaymentAmount();
RecalculateLoanAmount();
RecalculateSalesPrice();
propertiesChanged();
}
}
}
public double LoanAmount
{
get
{
return loanAmount;
}
set
{
if (loanAmount != value)
{
loanAmount = value;
// see above
RecalculateDownPaymentAmount();
RecalculateDownPaymentPercent();
RecalculateSalesPrice();
propertiesChanged();
}
}
}
private void propertiesChanged()
{
RaisePropertyChanged("SalesPrice", "DownPaymentAmount", "DownPaymentPercent", "LoanAmount");
}
Maybe you can concentrate the recalculations in less methods or even a single one, but I do not know how you calculate them. But certainly you have to keep a specific order when recalculating the values.
Since they only operate on fields and do not change the properties, there will be no PropertyChanged-feedback-loop.
Hope this helps and I did not misunderstood what you wanted.
What the OP wanted was something like following
class A : INotifyPropertyChanged
{
private int field1;
public int Property1
{
get { return field1; }
set
{
field1 = value;
field2++;
RaisePropertyChanged("Property1");
RaisePropertyChanged("Property2");
}
}
private int field2;
public int Property2
{
get { return field2; }
set
{
field2 = value;
field1++;
RaisePropertyChanged("Property1");
RaisePropertyChanged("Property2");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
What he might be doing was handling other properties in the setter of each property he mentioned thus leading to cyclic invocation of setters.
Vijay

Categories

Resources