Intercept a setter in C# [duplicate] - c#

This question already has answers here:
c#: getter/setter
(9 answers)
Closed 7 years ago.
I'm trying to learn C#, and am coming from Java. I've seen this in C#:
class A {
public string x { get; set; }
}
What do I do if I want to intercept the incoming value on the setter?

This is just syntactic sugar for
private string x;
public string X
{
get { return this.x; }
set { this.x = value; }
}
which is effectively what the compiler really outputs for your code, though you can't access the field x directly.
Always use this long form if you need to do anything beyond setting and retrieving the value from a field.

You can create a backing store:
private string _x;
public string x {
get {
return _x;
}
set {
// do something - you can even return, if you don't want the value to be stored
// this will store the value
_x = value;
// do something else
}
}

First you should make a private property that you will store the actual values in. In the get function just return that private property. In the set method you can use the value keyword to see the incoming value and do whatever you want before actually setting the private property;
public class A
{
private string xPrivate;
public string X {
get { return this.xPrivate; }
set { this.xPrivate = value; }}
}

Related

Alias a variable in Unity C#

I am looking for a way to declare an alias for a variable in Unity C#.
For example, in the following code:
struct Data
{
int value;
}
class Instance
{
private Data data;
public int value => data.value;
}
The => operator provides a read-only variable. I'm looking for a way to declare a variable that I can read and write to.
In C++ I would use the using keyword but that doesn't seem to work the same way in C#.
Any help would be appreciated, thanks!
The using directive in c# (not to be confused with the using statement block) is used for having aliases for TYPES and NAMESPACES - not fields - e.g.
using BecauseICan = System.Collections.Generic.List<int>;
public class Instance
{
public BecauseICan x = new BecauseICan();
}
The => is a read-only Property in "expression body" notation and basically equals writing
// explicit getter but still as expression body
public int value
{
get => data.value;
}
or also
// completely written out
public int value
{
get
{
return data.value;
}
}
As you can see it is simply the missing setter which makes it read-only.
So what speaks against using e.g.
// Note: I'm not sure if even possible but I guess it is not a good idea to call a property "value"
// "value" is a keyword within the property - see the setter
// again with expression body getter and setter
public int Value
{
get => data.value;
set => data.value = value;
}
or also
// explicit written out
public int Value
{
get
{
return data.value;
}
set
{
data.value = value;
}
}
Either way the Data.value needs to be public otherwise you can't access it from Instance at all.
You are looking for Properties
A property is a member that provides a flexible mechanism to read,
write, or compute the value of a private field.
//Just for sake of understanding I updated name of class and property
public class Student
{
private Data data;
public int RollNumber
{
get { return data.value; }
set { data.value = value; }
}
}
Now you can write/read the value of RollNumber property by,
Student instance = new Student();
instance.RollNumber= 123; //Assign 123 to Value
Console.WriteLine(instance.RollNumber); //Read value of property i.e 123
You can use a property with a getter and setter on the private backing field.
You will also have to make sure that value is accessible (internal/public)
struct Data
{
public int value;
}
public class Instance
{
private Data data;
public int value
{
get => data.value;
set => data.value = value;
}
}

How to make a variable able to be set only once in C#? [duplicate]

This question already has answers here:
Is there a way of setting a property once only in C#
(14 answers)
Closed 2 years ago.
I want to declare a variable, and assign it later, but I want the variable to be able to be assigned once.
The readonly keyword doesn't do this. The documentation says:
assignment to the field can only occur as part of the declaration or in a constructor in the same class.
The const keyword also doesn't do this.
So how do I make a variable able to be set only once?
Thanks in advance!
You can use a private nullable variable like this, in this way, _myVar just once gets value
private bool? _myVar = null;
public bool? MyVar
{
set { if (_myVar == null) _myVar = value; }
get { return _myVar; }
}
To do this, first you have to make a bool variable that tells you if the variable has been set:
bool isSet;
Then, we make the variable be true when the variable you want to be able to be set only once is set.
private int exampleVar
public int ExampleVar {
get {
return exampleVar;
}
set {
if(isSet) {
exampleVar = value;
}
}
}
Note that this returns null if this variable is accessed before it is set.
To fix it, replace everything inside get{} with:
if(isSet) {
return exampleVar;
}
return /* insert placeholder variable here */;
This also works if exampleVar and ExampleVar is another type of variable, such as float.

Parsing within a Set method

I know this might be a simple question but I was wondering in C# what is the best way to parse an incoming string within a set method to an int e.g. if I have
public int foo {get; set;}
On the set I want to parse a incoming string
There are a lot of ways to skin this cat. This is how I would do it.
Let's say your property is:
public int Foo
{
get { return _foo; }
set { _foo = value; }
}
You could do is add a helper method on your class:
public void SetFoo(string sFoo)
{
Foo = Convert.ToInt32(sFoo);
}
Then, when you need to set the value using a string, you can call that method:
myFooObject.SetFoo("4");
I guess you have some string and you want to parse it into int by setter. Of course, you can do it, but the property must be string.
private int foo
public string Foo
{
get
{
return foo.ToString();
}
set
{
foo = Int32.Parse(value);
}
}
But remember that Int32.Parse() throws an exception if your string is not a number. You should consider using Int32.TryParse() which could be a better choice in this case.
Do you mean this?
private int _foo;
public int Foo
{
get { return _foo; }
set
{
_foo = value;
ParseFoo(_foo);
}
}
but since you're talking about strings...
private string _foo;
public string Foo
{
get { return _foo; }
set {
_foo = value;
ParseIncomingString(_foo);
}
}
Well since the property is of type int, it's not possible to assign a string to it. So you need to do this parsing before assigning the value to your property.
Alternatively you could make your setter private, and have a public method that takes string, and do your validation inside of the method set the property if validation succeeds.
I would recommend you to make sure that your value is an int before you set it to your property when the set method is called automatically. This means that the string you want to set to your property should be parsed before it's set.
If you want to do it as you asked then you could simply use the Int32.Parse(value) or Int32.TryParse(value).
The difference between those two is that Parse(value) method throws an exception if the the parsing fails which means that you have to use try-catch block if you want to catch the exception and where TryParse(value) returns false if the parsing fails and true on success.
You can read more at: https://msdn.microsoft.com/en-us/library/bb397679.aspx

(Duplicated) Difference between 'public int x;' and 'public int x { get; set; }

What is the difference, if any, between
public int x;
and
public int x { get; set; }
?
The first one is called a field. The second one is a property, in this case an auto-implemented property.
Properties act like fields but use a getter and a setter function to retrive and set the value. Another way of writing the above property is as follows:
private int _x;
public int X
{
get
{
return _x;
}
set
{
_x = value;
}
}
The variable _x in this case is called a backing field. With an auto-implemented property you can't access the backing field or customize code in the getter/setter, but if you don't need to than it's shorter and more succinct.
As a rule in C# most of the time any public member should be exposed as a property instead of a field.
The difference between thise two is that a property can do something more than just get / set a variable.
take this example:
private int _x;
public int x
{
get
{
//do something
return _x;
}
set
{
if(_x != value)
PropertyChanged("x");
_X = value;
}
}
when we set the property - we notify something ( PropertyChanged()) that the value has changed. It would be very hard to do with just the field
The first one is public variable which can be accessed from anywhere.
The second one is public property
Check Properties tutorial for details.
Properties have many uses: they can validate data before allowing a
change; they can transparently expose data on a class where that data
is actually retrieved from some other source, such as a database; they
can take an action when data is changed, such as raising an event, or
changing the value of other fields.

Stack Overflow exception while setting static property C# [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
New to C#, why does Property Set throw StackOverflow exception?
I'm getting a stack overflow exception when I try to set a static property.
public static class StaticTest
{
static string stringToSet
{
get
{
return stringToSet;
}
set
{
stringToSet = value;
}
}
}
Then, in other class:
public void setStaticProperty()
{
StaticTest.stringToSet = "Hello World"; // StackOverflow exception here
}
What I'm doing wrong?
set
{
stringToSet = value;
}
You got infinite recursion in your setter (and getter for that matter) since it calls itself, hence StackOverflow.
If you don't need to modify the underlying field directly, use an auto-property instead:
static string stringToSet {get; set;}
In your static property setter, you are assigning a value to the static property stringToSet, which calls your static property setter, where you are assigning a value to the static property stringToSet, which calls your static property setter, where you are assigning a value to the static property stringToSet, which calls your static property setter, where you are assigning a value to the static property stringToSet ...
You need to add a private field to store the property value; usually you'd then rename the property to start with a capital letter (StringToSet).
private string stringToSet;
public string StringToSet {
get {
return stringToSet;
}
set {
stringToSet = value;
}
}

Categories