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"));
}
Related
I am fairly new to programming and C#, and I am creating a game using C# 9.0 in which all instances of Entity have certain stats. I want to be able to change their private data fields using properties, though I'm not entirely sure how properties work. I know they are useful in encapsulation as getters and setters.
Context:
I am trying to optimize code and decrease memory usage where possible
The byte field str should be variable (through events, training, etc.), but have a "ceiling" and "floor"
If dog.str = 253, then dog.Str += 5; should result in dog.str being 255
If dog.str = 2, then dog.Str -= 5; should result in dog.str being 0
private byte str;
public short Str
{
get => str;
set
{
if (value > byte.MaxValue) str = byte.MaxValue; //Pos Overflow
else if (value < byte.MinValue) str = byte.MinValue; //Neg Overflow
else str = (byte)value;
}
}
Questions:
Since the property is of datatype Short, does it create a new private backing field that consumes memory? Or is value/Str{set;} just a local variable that later disappears?
Does the property public float StrMod {get => (float)(str*Effects.Power);} create a backing field? Would it be better to just create a method like public float getStrMod() instead?
Is this code optimal for what I'm trying to achieve? Is there some better way to do this, considering the following?
If for some reason the Short overflowed (unlikely in this scenario, but there may be a similar situation), then I would end up with the same problem. However, if extra memory allocation isn't an issue, then I could use an int.
The {get;} will return a Short, which may or may not be an issue.
Question 1:
No it doesn't, its backing field is str.
Question 2:
Profile your code first instead of making random changes in hope to reduce memory usage.
"Premature optimization is the root of all evil", do you really have such issues at this point ?
Personally I'd use int and use same type for property and backing field for simplicity.
This would avoid wrapping such as assigning 32768 which would then result as -32768 for short.
Side note, don't think that using byte necessarily results in 1 byte, if you have tight packing requirements then you need to look at StructLayoutAttribute.Pack.
Other than that I see nothing wrong with your code, just get it to work first then optimize it!
Here's how I'd write your code, maybe you'll get some ideas from it:
class Testing
{
private int _value;
public int Value
{
get => _value;
set => _value = Clamp(value, byte.MinValue, byte.MaxValue);
}
private static int Clamp(int value, int min, int max)
{
return Math.Max(min, Math.Min(max, value));
}
}
EDIT:
Different scenarios:
class Testing
{
private int _value1;
public int Value1 // backing field is _value1
{
get => _value1;
set => _value1 = value;
}
public int Value2 { get; set; } // adds a backing field
public int Value3 { get; } // adds a backing field
public int Value4 => 42; // no backing field
}
As you might have guessed, properties are syntactic sugar for methods, they can do 'whatever' under the hood compared to a field which can only be assigned a value to.
Also, one difference with a method is that you can browse its value in the debugger, that's handy.
Suggested reading:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties
Finally, properties are expected to return quickly, else write a method, and possibly async if it's going to take a while (advantage to method in this case as properties can't be async).
#aybe answer covers main thing about you question. I would like to add additional info to your 2nd question. You should consider on which platform you write application. There is a word term:
In computing, a word is the natural unit of data used by a particular
processor design. A word is a fixed-sized piece of data handled as a
unit by the instruction set or the hardware of the processor. The
number of bits in a word (the word size, word width, or word length)
is an important characteristic of any specific processor design or
computer architecture.
If processor has 64 bit word, then every variable which type is less than 64 bits will still occupy 64 bits in memory. Keep in mind that variable of given type will be handled as given type and size in memory doesn't impact range, overflow or underflow - arithmetic will be processed for given type.
In short - if you have 64-bit desktop processor and you will use only short variables, then you will not observe any memory savings in comparison to declaring int variables.
I did this once a long time ago and followed a design pattern when I did. Now, I need to do it again, I don't really remember how I did it before, and I can't think of the pattern that helped me do it.
I have a class with a whole slew of variables/properties. Some are calculated based on the others, and there is all sorts of cross-calculating going on between these properties.
It's all fine when I first instantiate - all the values and the calculations work just fine. My problem is, when one value changes, I want all of the calculated values derived from it to update themselves based on the new value automatically. And I don't want to write each individual recalc manually if I don't have to - it just becomes a lot of overhead whenever this class gets updated or added to, trying to track down all of the places you need to propagate whatever change you're making.
I think you follow me.
Anyway, can anyone think of what pattern it is that makes this possible? I swear I used to know it. Getting old I guess.
// Like this...
class foo
{
decimal A = 1233;
decimal B = 42;
decimal C = A / B; // I want this to update whenever
// the value of either A or B changes.
decimal D = 123;
decimal E = 321;
decimal F = D + E; // I don't want this one to change when
// A or B or even C for that matter changes,
// and I don't wan to have to cycle through
// all of the calculated values that don't
// need to change just for find the few that do.
}
Observer. You need some kind of .Subscribe() method on your models that is used to register callbacks - in your specific cases those are just functions that take new value and recompute some others based on that one. As long as your programming environment has rxjs implementation(s), I strongly suggest to stick to that one. Otherwise you'll suffer because of multithreading and memory leaks.
I'd suggest to avoid over-engineering here. What you presented as an example has 6 members with simple dependencies between them that can be easily recalculated. I do understand this can be just a simplified example, so let's aim for e.g. 10-20 members, and dependencies that don't require database lookups or disk access (as an example of heavier operations).
You can put all dependencies into one method (let's call it Update), which you call if any member is modified. To not worry about remembering to call Update(), you move all members into a separate "state" class:
class FooState
{
private int _a;
public int A
{
get { return _a; }
set
{
_a = value;
Update();
}
}
private int _b;
public int B
{
get { return _b; }
set
{
_b = value;
Update();
}
}
public double C { get; private set; }
// other members
private void Update()
{
C = A * B + 3;
// other updates
}
}
class Foo
{
private FooState _state;
public Foo()
{
_state.A = 1;
_state.B = 2;
Debug.Write($"C = {_state.C}");
}
}
What you get:
It's immediately clear what's going on. To anybody who will happen to
modify this code.
all dependencies between your members are in a single method, easy to read, easy to modify. Your business logic is not polluted with this details.
You can't forget to recalculate your dependent members.
Yes you can do more recalculation than strictly required, as you recalculate all your dependent members even if an unrelated member was modified. In the majority of similar cases I've seen in real file this wasn't a problem.
This approach doesn't work if you have cyclic dependencies (which is a different story).
Feel free to implement "observer" pattern and compare.
I don't think this simple approach has the name. Don't confuse it with "State" pattern which is a bit different thing.
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 a property like so:
private Decimal _payout;
public Decimal PayoutValue
{
get { return _payout; }
set
{
_payout = value;
//second part of following conditional is an enum
if (Math.Abs(value) > 1 && this.PayoutType == CutType.Percent)
{
_payout /= 100;
}
}
}
As you can see, it is dependent upon the value of PayoutType, which is just a simple enum property:
public CutType PayoutType { get; set; }
My problem is that PayoutType doesn't seem to get set before PayoutValue is set, so the conditional below is never true. How do I force the PayoutType to be set before PayoutValue is evaluated?
Thanks.
UPDATE Thanks for your answers guys. I guess I should have mentioned that most of the time this object is bound via DataContexts or from an Http.Post from my client side (MVC project), so I don't really have any constructors. Is there any other way, or should I start getting creative with my programming?
How do I force the PayoutType to be set before PayoutValue is evaluated?
Put it in the constructor. That's the only way to enforce this rule.
That being said, I would recommend against this, at least in your implementation above. Your current property implementation will be very, very confusing to users. People tend to expect that setting a property, then immediately fetching it will provide the same value.
In your case, though:
decimal value = 45.3;
myObject.PayoutValue = value; // Set this
if (myObject.PayoutValue != value)
{
// This would normally be a very unexpected case! In your example, it will always be true!
}
It would be much better to potentially use two properties, or a method (ie: SetPayoutValue(decimal value)) to clue the user into the fact that it's not acting like a simple property.
How about this ?
get
{
if (Math.Abs(value) > 1 && this.PayoutType == CutType.Percent)
{
return _payout /100;
}
return _payout;
}
set{_payout = value;}
So that you do not change the value that was set.
All "required" properties should be in the constructor of your class.
I'm looking for the C# equivalent of Java's final. Does it exist?
Does C# have anything like the following:
public Foo(final int bar);
In the above example, bar is a read only variable and cannot be changed by Foo(). Is there any way to do this in C#?
For instance, maybe I have a long method that will be working with x, y, and z coordinates of some object (ints). I want to be absolutely certain that the function doesn't alter these values in any way, thereby corrupting the data. Thus, I would like to declare them readonly.
public Foo(int x, int y, int z) {
// do stuff
x++; // oops. This corrupts the data. Can this be caught at compile time?
// do more stuff, assuming x is still the original value.
}
Unfortunately you cannot do this in C#.
The const keyword can only be used for local variables and fields.
The readonly keyword can only be used on fields.
NOTE: The Java language also supports having final parameters to a method. This functionality is non-existent in C#.
from http://www.25hoursaday.com/CsharpVsJava.html
EDIT (2019/08/13):
I'm throwing this in for visibility since this is accepted and highest on the list. It's now kind of possible with in parameters. See the answer below this one for details.
This is now possible in C# version 7.2:
You can use the in keyword in the method signature. MSDN documentation.
The in keyword should be added before specifying a method's argument.
Example, a valid method in C# 7.2:
public long Add(in long x, in long y)
{
return x + y;
}
While the following is not allowed:
public long Add(in long x, in long y)
{
x = 10; // It is not allowed to modify an in-argument.
return x + y;
}
Following error will be shown when trying to modify either x or y since they are marked with in:
Cannot assign to variable 'in long' because it is a readonly variable
Marking an argument with in means:
This method does not modify the value of the argument used as this parameter.
The answer: C# doesn't have the const functionality like C++.
I agree with Bennett Dill.
The const keyword is very useful. In the example, you used an int and people don't get your point. But, why if you parameter is an user huge and complex object that can't be changed inside that function? That's the use of const keyword: parameter can't change inside that method because [whatever reason here] that doesn't matters for that method. Const keyword is very powerful and I really miss it in C#.
Here's a short and sweet answer that will probably get a lot of down votes. I haven't read all of the posts and comments, so please forgive me if this has been previously suggested.
Why not take your parameters and pass them into an object that exposes them as immutable and then use that object in your method?
I realize this is probably a very obvious work around that has already been considered and the OP is trying to avoid doing this by asking this question, but I felt it should be here none-the-less...
Good luck :-)
I'll start with the int portion. int is a value type, and in .Net that means you really are dealing with a copy. It's a really weird design constraint to tell a method "You can have a copy of this value. It's your copy, not mine; I'll never see it again. But you can't change the copy." It's implicit in the method call that copying this value is okay, otherwise we couldn't have safely called the method. If the method needs the original, leave it to the implementer to make a copy to save it. Either give the method the value or do not give the method the value. Don't go all wishy-washy in between.
Let's move on to reference types. Now it gets a little confusing. Do you mean a constant reference, where the reference itself cannot be changed, or a completely locked, unchangeable object? If the former, references in .Net by default are passed by value. That is, you get a copy of the reference. So we have essentially the same situation as for value types. If the implementor will need the original reference they can keep it themselves.
That just leaves us with constant (locked/immutable) object. This might seem okay from a runtime perspective, but how is the compiler to enforce it? Since properties and methods can all have side effects, you'd essentially be limited to read-only field access. Such an object isn't likely to be very interesting.
Create an interface for your class that has only readonly property accessors. Then have your parameter be of that interface rather than the class itself. Example:
public interface IExample
{
int ReadonlyValue { get; }
}
public class Example : IExample
{
public int Value { get; set; }
public int ReadonlyValue { get { return this.Value; } }
}
public void Foo(IExample example)
{
// Now only has access to the get accessors for the properties
}
For structs, create a generic const wrapper.
public struct Const<T>
{
public T Value { get; private set; }
public Const(T value)
{
this.Value = value;
}
}
public Foo(Const<float> X, Const<float> Y, Const<float> Z)
{
// Can only read these values
}
Its worth noting though, that its strange that you want to do what you're asking to do regarding structs, as the writer of the method you should expect to know whats going on in that method. It won't affect the values passed in to modify them within the method, so your only concern is making sure you behave yourself in the method you're writing. There comes a point where vigilance and clean code are the key, over enforcing const and other such rules.
I know this might be little late.
But for people that are still searching other ways for this, there might be another way around this limitation of C# standard.
We could write wrapper class ReadOnly<T> where T : struct.
With implicit conversion to base type T.
But only explicit conversion to wrapper<T> class.
Which will enforce compiler errors if developer tries implicit set to value of ReadOnly<T> type.
As I will demonstrate two possible uses below.
USAGE 1 required caller definition to change. This usage will have only use in testing for correctness of your "TestCalled" functions code. While on release level/builds you shouldn't use it. Since in large scale mathematical operations might overkill in conversions, and make your code slow. I wouldn't use it, but for demonstration purpose only I have posted it.
USAGE 2 which I would suggest, has Debug vs Release use demonstrated in TestCalled2 function. Also there would be no conversion in TestCaller function when using this approach, but it requires a little more of coding of TestCaller2 definitions using compiler conditioning. You can notice compiler errors in debug configuration, while on release configuration all code in TestCalled2 function will compile successfully.
using System;
using System.Collections.Generic;
public class ReadOnly<VT>
where VT : struct
{
private VT value;
public ReadOnly(VT value)
{
this.value = value;
}
public static implicit operator VT(ReadOnly<VT> rvalue)
{
return rvalue.value;
}
public static explicit operator ReadOnly<VT>(VT rvalue)
{
return new ReadOnly<VT>(rvalue);
}
}
public static class TestFunctionArguments
{
static void TestCall()
{
long a = 0;
// CALL USAGE 1.
// explicite cast must exist in call to this function
// and clearly states it will be readonly inside TestCalled function.
TestCalled(a); // invalid call, we must explicit cast to ReadOnly<T>
TestCalled((ReadOnly<long>)a); // explicit cast to ReadOnly<T>
// CALL USAGE 2.
// Debug vs Release call has no difference - no compiler errors
TestCalled2(a);
}
// ARG USAGE 1.
static void TestCalled(ReadOnly<long> a)
{
// invalid operations, compiler errors
a = 10L;
a += 2L;
a -= 2L;
a *= 2L;
a /= 2L;
a++;
a--;
// valid operations
long l;
l = a + 2;
l = a - 2;
l = a * 2;
l = a / 2;
l = a ^ 2;
l = a | 2;
l = a & 2;
l = a << 2;
l = a >> 2;
l = ~a;
}
// ARG USAGE 2.
#if DEBUG
static void TestCalled2(long a2_writable)
{
ReadOnly<long> a = new ReadOnly<long>(a2_writable);
#else
static void TestCalled2(long a)
{
#endif
// invalid operations
// compiler will have errors in debug configuration
// compiler will compile in release
a = 10L;
a += 2L;
a -= 2L;
a *= 2L;
a /= 2L;
a++;
a--;
// valid operations
// compiler will compile in both, debug and release configurations
long l;
l = a + 2;
l = a - 2;
l = a * 2;
l = a / 2;
l = a ^ 2;
l = a | 2;
l = a & 2;
l = a << 2;
l = a >> 2;
l = ~a;
}
}
If you often run into trouble like this then you should consider "apps hungarian". The good kind, as opposed to the bad kind. While this doesn't normally tries to express constant-ness of a method parameter (that's just too unusual), there is certainly nothing that stops you from tacking an extra "c" before the identifier name.
To all those aching to slam the downvote button now, please read the opinions of these luminaries on the topic:
Eric Lippert
Larry Osterman
Joel Spolsky
If struct is passed into a method, unless it's passed by ref, it will not be changed by the method it's passed into. So in that sense, yes.
Can you create a parameter whose value can't be assigned within the method or whose properties cannot be set while within the method? No. You cannot prevent the value from being assigned within the method, but you can prevent it's properties from being set by creating an immutable type.
The question isn't whether the parameter or it's properties can be assigned to within the method. The question is what it will be when the method exits.
The only time any outside data is going to be altered is if you pass a class in and change one of it's properties, or if you pass a value by using the ref keyword. The situation you've outlined does neither.
The recommended (well, by me) is to use an interface that provides read only access to the members. Remembering that if the "real" member is a reference type, then only provide access to an interface supporting read operations for that type -- recursing down the entire object hierarchy.