How to lock/unlock a field at runtime in C#? - c#

Can I lock/unlock fields or objects at runtime against writing? In other words something like changing objects to read-only temporarily at runtime...
For example:
int x = 5; // x is 5
LockObject(x);
x = 7; // no change
UnlockObject(x);
x = 10; // x is 10
if not can you give me some possible solutions?

You can use accessors to do this...
public class X
{
private bool locked = false;
private int lockedVar;
public int LockedVar
{
get { return lockedVar; }
set { if (!locked) lockedVar = value; }
}
public void LockObject() { locked = true; }
public void UnlockObject() { locked = false; }
}

Wrap it in a property and then use a boolean flag as the "lock".
You can also use a struct to handle this type of logic.
public struct LockableInt
{
private int _value;
public bool Locked;
public void Lock(bool locked) {Locked = locked;}
public int Value
{
get
{ return _value; }
set
{ if (!Locked) _value = value; }
}
public override string ToString()
{
return _value.ToString();
}
}
Sample client code:
public static void RunSnippet()
{
LockableInt li = new LockableInt();
li.Value = 5;
Console.WriteLine(li.ToString());
li.Lock(true);
li.Value = 6;
Console.WriteLine(li.ToString());
li.Lock(false);
li.Value = 7;
Console.WriteLine(li.ToString());
}
Output:
5
5
7
Press any key to continue...

Thanks all for help. Here is a more generalized alternative.
I have decided that it would be more convenient to use freeze/unfreeze since lock/unlock exists in the context of multithreading programming.
public class FreezeableValue<T>
{
private bool frozen;
private T value;
public FreezeableValue()
{
frozen = false;
}
public FreezeableValue(T value)
{
this.value = value;
frozen = false;
}
public void Freeze(bool frozen)
{
this.frozen = frozen;
}
public T Value
{
get { return value; }
set
{
if (!frozen) this.value = value;
}
}
}

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!

No overload for method '' takes 1 argument

Well, my issue here is basically what it says in the title. I'm trying to call my bool value of my Player2 class for my Tic Tac Toe-project we have in school. I think it's worth mentioning that I use "Player Player1, Player2;" in the beginning of Form1.cs to create two instances of my class, Player. I've read multiple posts on the internet about this but all of them are people trying to call in more parameters than that they are providing. I don't see how a bool value of true or false is more than one.
Thanks in advance.
One of my buttons where this problem appears.
public void Btn1_Click(object sender, EventArgs e) >{
{
if (click1 == 0)
{
if (Player2.GetActive(true))//(turn == 0)
{
Btn1.Text = "X";
}
else
{
>Btn1.Text = "O";
}
//turn++;
click1++;
}
else
{
Btn1.Text = Btn1.Text;
}
display();
checkit();
}
}
This is my player class.
` public class Player
{
//Characteristics
string name;
int points;
bool Active;
//Constructor
public Player() { points = 0; Active = true; }
//Methods
public void SetName(string n) { name = n; }
public string GetName() { return name; }
public void SetPoints(int p) { points = p; }
public int GetPoints() { return points; }
public void SetActive(bool a) { Active = a; }
public bool GetActive() { return Active; }`
You have the code:
Player2.GetActive(true)
But you define get active as
public bool GetActive() { return Active; }`
So it is correct you have not defined a GetActive with a parameter.
Here,
if(Player2.GetActive(true))
you are passing an extra argument (true) to the method GetActive. As we can see from the method declaration of GetActive, it takes no parameters:
public bool GetActive() { return Active; }
// ↑
// empty parentheses
I think what you mean here is "if Player2.GetActive() is true..." right? You don't need to specify the value you want if it is true, just doing this is fine:
if (Player2.GetActive())
If you want to check if it is false, add ! before the call to negate the result:
if (!Player2.GetActive())
Like BugFinder said, you are using the method to get the Active-Value instead of using the method to set the value.
So change
Player2.GetActive(true)
to
Player2.SetActive(true)
Just as an addition:
Since we are working with C# here and many of your methods are called set and get, I suggest you change those methods to be properties:
public string Name
{
get { return name; }
set { name = value; }
}
public int Points
{
get { return points; }
set { points = value; }
}
public bool Active
{
get { return active; }
set { active = value; }
}
Now when you want to set the value, you can type
Player2.IsActive = true;
and to check the value simple type code like
If(Player2.IsActive)
//Do Stuff

Global Variables Return Unexpected Values

Well I was trying to assign global variable to read values from Check boxes and radio buttons but the values don't update when the selections are changed ! Where have I done wrong? Here's the code:
private void chkInMut_Checked(object sender, RoutedEventArgs e)
{
GlobalVar.Mutate = 1;
}
private void chkShwCal_Checked(object sender, RoutedEventArgs e)
{
GlobalVar.ShowCal = 1;
}
private void chkOutSol_Checked(object sender, RoutedEventArgs e)
{
GlobalVar.OutCal = 1;
}
}
public static class GlobalVar
{
static int _MaxMin, _MutVal, _CalShow, _CalOut;
/// <summary>
/// Access routine for global variable.
/// </summary>
public static int Extrema
{
get
{
return _MaxMin;
}
set
{
_MaxMin = value;
}
}
public static int Mutate
{
get
{
return _MutVal;
}
set
{
_MutVal = value;
}
}
public static int ShowCal
{
get
{
return _CalShow;
}
set
{
_CalShow = value;
}
}
public static int OutCal
{
get
{
return _CalOut;
}
set
{
_CalOut = value;
}
}
}
when I try to print the numbers using this test satement, the values returned are unexpected :
maxMin = GlobalVar.Extrema;
calShow = GlobalVar.ShowCal;
calOut = GlobalVar.OutCal;
IsMutble = GlobalVar.Mutate;
txtOutput.Text += Convert.ToString("\nMaxima Minima"+maxMin+"\n"+"Show Cal : "+calShow+"\n"+"Output Cal :"+calOut+"\n"+"Mutate : "+IsMutble+"\n---------\n");
And when I check/un-check the boxes, the values are not updated as it should be. Where have I gone wrong?
Edit: Solved by adding Unchecked Parameter.
Probably you should write your event handlers like this
private void chkInMut_Checked(object sender, RoutedEventArgs e)
{
GlobalVar.Mutate = (chkInMut.IsChecked ? 1 : 0);
}
and so on .....
I think the problem is with your public static properties. for example try this:
public static int Extrema
{
get
{
return GlobalVar._MaxMin;
}
set
{
GlobalVar._MaxMin = value;
}
}
and do the same for all other properties.
Edit:
and why are you using this stucture? You can set your static class to be like this:
public static class GlobalVar
{
public static int Extrema;
public static int Mutate;
public static int ShowCal;
}

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

Having multiple properties incrementing one variable. Simple check of its value?

I have 10 properties where when each is set it increments the value of variable Value. When the value of Value is 10, the app will end. But it seems to be awkward to write the same condition into each of them like this:
int Value=0;
int A
{
set
{
a=value;
Value++;
if(Value>10) ... //check here
}
}
int B
{
set
{
b=value;
Value++;
if(Value>10) //check here again
}
}
How can I simplify checking its value?
You could make a private property for Value and in the setter of that property, if the value is set to above 10, exit the application.
private int value=0;
private int a, b;
public int A
{
set
{
this.a = value;
Value++;
}
get { return this.a; }
}
public int B
{
set
{
this.b = value;
Value++;
}
get { return this.b; }
}
private int Value
{
set
{
this.value = value;
if (this.value > 10)
{
// Exit.
}
}
get { return this.value; }
}
I'm assuming that your properties are in a class which has other responsibilities than exiting the program when the counter hits 10. If so, I would remove the logic of checking the counter and exiting the app from the class.
Maybe you can use an event. The subscriber to this event will be notified when Value hits 10 (you could actually make "10" configurable, but this is just a short example) and exit the app.
class YourClass {
public event ValueHandler ValueIs10;
public EventArgs e = null;
public delegate void ValueHandler(YourClass m, EventArgs e);
private int _value=0;
public int Value {
get {return _value;}
private set {
_value=value;
if(_value==10 && ValueIs10 != null) ValueIs10(this, e);
}
}
public int A
{
set
{
a=value;
Value++;
}
}
public int B
{
set
{
b=value;
Value++;
}
}
// ...
}
private int counter;
private int b;
private int a;
public int A
{
set
{
counter++;
a = value;
CheckCounter();
}
}
public int B {
set
{
counter++;
b = value;
CheckCounter();
}
}
public void CheckCounter()
{
if (counter>10)
{
//Do something
}
}
or make counter a property..
private int Counter
{
set
{
counter = value;
CheckCounter();
}
get
{
return counter;
}
}
and use this when incrementing..
Counter++;
Both answers from #Richard and #Emil are correct, but to make your code more expandable in the future, it's better to implement the built-in INotifyPropertyChanged interface.
class Data : INotifyPropertyChanged
{
private int _counter = 0;
public event PropertyChangedEventHandler PropertyChanged = (sender, arg) =>
{
// if (_counter > 10) Exit();
// from arg you can know what property is changed
// which is probably used for future
};
private int _number;
public int Number
{
get { return _number; }
set
{
//here is another unclear point in your question
//will the counter increases when setting a.Number = 100
//but it's already 100 before setting
if (_number != value)
{
_number = value;
PropertyChanged(this, new PropertyChangedEventArgs("Number"));
}
}
}
}

Categories

Resources