C# Class member validation without having Private members - c#

Is there a way to conduct error range checking in C# for class members, without Private members?
1)
For example here, I Need Private member for (less than/greater than checking).
public class PageModel
{
private int page;
public int Page
{
get => page;
set
{
if (value < 0) { page = 0; }
else page = value;
}
}
2)
If only have Public member, the get=> Page line gives SonarQube error
Add a way to break out of this property accessor's recursion
public class PageModel
{
public int Page
{
get => Page;
set
{
if (value < 0) { Page = 0; }
else Page = value;
}
}
Just curious if there is way to conduct data validation without private member. Are data annotations good method also? are they as safe as private members?

Question answered before OP's edit
Property is not a field, it is just shorthand for:
private int <>_page;
public get_Page()
{
return <>_page;
}
public set_Page(int value)
{
<>_page = value;
}
So setting Page like that doesn't make any sense.
public int Page
{
get => Page;
}
Answering your question, no, there is no way to get rid of additional field, because there is nothing to write to if you get rid of the field.
You would have to create a method such as
public int Page { get; set; }
public void Validate()
{
if(Page < 0)
Page = 0;
}
But there are endless possibilities of doing it.

Related

C# get/set inheritance?

I am not sure this is syntactically possible. If I have duplicate logic that would go in a getter/setter. Is there a way for a variable to inherit that pattern instead of re-typing the code.
private int basicVar;
public int BasicVar
{
get { return basicVar; }
set
{
if (IsServer)
{
basicVar = value;
Debug.Log("The variable name is: " + nameof(BasicVar));
//Other code
}
}
}
private int turn
public int Turn
{
//Inherits from basicVar
}
I am not sure if such a thing is possible, I was just curious.
(If it is, how could I template the private variable?)
I could do this by making it its own class, but I would prefer to keep it a primitive.
As mentioned in the comments, when needing to build reusable behavior, the preferred approach is to encapsulate the behavior in functions that can be called instead of the getter/setter of the property itself. This allows you to clearly define your expected behavior and allows you to easily compose logic by calling other methods.
public class Test
{
public bool IsServer { get; set; }
public int BasicVar { get; set }
public int Turn { get; set; }
public void UpdateBasicVar(int updatedValue)
{
if (IsServer)
{
BasicVar = updatedValue;
Debug.Log("The variable name is: " + nameof(BasicVar));
//Other code
}
}
public void UpdateTurnAndBasicVar(int updatedValue)
{
Turn = updatedValue;
Debug.Log("The variable name is: " + nameof(Turn));
UpdateBasicVar(updatedValue);
}
}
This also helps prevent side effects in your code. Typically, when using properties, C# developers expect that interacting with that property ONLY affects that property. It is not expected that updating one property would also update another.
Consider the following example:
public class SideEffects
{
private int basicVar;
public int BasicVar
{
get { return basicVar; }
set
{
if (IsServer)
{
basicVar = value;
Debug.Log("The variable name is: " + nameof(BasicVar));
//Other code
}
}
}
private int turn;
public int Turn
{
get { return turn; }
set
{
turn = value;
BasicVar = value;
}
}
}
while this is essentially functionally equivalent to the previous method-based example, it is no longer self-documenting. There is no way to determine from the public contract of the class that updating Turn will also update BasicVar, which is considered a side effect.

Understand function from get set method

I am using a get set method to loop another method. As shown below, I am trying to increase the value of Table10_3 in the ValuesForTableLooping class. In the Main method, I have called the get set property to increase the value by one.
I have 2 questions at hand,
Is there a way to call the get set method without putting it as Inc.Val = 0;?
Why does changing any value in Inc.Val = 0; not affect the outcome?
class Class2
{
public class ValuesForTableLooping
{
public static int Table10_3 = 1;
}
public static void Main()
{
Console.WriteLine(ValuesForTableLooping.Table10_3);
Increase Inc = new Increase();
Inc.Val = 0;
Console.WriteLine(ValuesForTableLooping.Table10_3);
Inc.Val = 0;
Console.WriteLine(ValuesForTableLooping.Table10_3);
Inc.Val = 0;
Console.WriteLine(ValuesForTableLooping.Table10_3);
}
public class Increase
{
private int val;
public int Val
{
get { return val; }
set { val = ValuesForTableLooping.Table10_3++; }
}
}
}
Thank you so much once again!
Your design is pretty strange and you seem to have a great misunderstanding on what properties are.
A property is nothing - as you noticed - as a get- and a set-method. So you could achieve the exact same with the following code:
public int get_Val() { return val; }
public void set_Val(int value) { val = ValuesForTableLooping.Table10_3++; }
And here is the weird thing. A setter expects a new value for your property, which is provided as value. However you donĀ“t use that value at all in your implementation. Instead you just increase val by one, which I would call a really strange design. You either want to set the new value from the outside with this:
public void set_Val(int value) { val = value; }
or in the property-notation:
public int Val {
get { return val; }
set { val = value; }
}
which can be further simplified by using an auto-implemented property:
public int Val { get; set; }
Another - IMHO better - way is to omit the setter completely and create some IncreaseVal-method instead:
public void IncreaseVal() { ValuesForTableLooping.Table10_3++; }
Last but not least Increase is a very bad name for a class. It does not describe a thing, but something you can do with a thing.

Updating an object from another objects property history in C# for implementing a PATCH

I'm trying to implement a PATCH on Web API for an object that will be stored in a DB. The input object from the controller has all of the properties that can be modified but we allow the client to choose which fields to send back. We only want to update the MongoDB representation if some of the fields have changed or been set. We started using a Dirty object pattern (not sure this is a pattern) whereby when you set a property you also record that it is dirty. for instance
public class Example
{
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
TitleWasSet = true;
}
}
public bool TitleWasSet {get;set;}
}
This could work but is kind of tedious and I feel it exposes lots of logic that could be contained.
So a solution I came up with was to store the update Actions in the inbound object then reapply them to the Mongo Object in a Try Update fashion.
like this:
public class Data
{
public string Header { get; set; }
public int Rating { get; set; }
}
public class EditDataRequest
{
private readonly List<Action<Data>> _updates;
public EditDataRequest()
{
_updates = new List<Action<Data>>();
}
public string Header
{
set
{
_updates.Add(data => {data.Header = value;});
}
}
public int Rating
{
set
{
_updates.Add(data => {data.Rating = value;});
}
}
public bool TryUpdateFromMe(Data original)
{
if (_updates.Count == 0)
return false;
foreach (var update in _updates)
{
update.Invoke(original);
}
return true;
}
}
Now this would work great but it doesn't take account of the values being the same. So i then looked at changing the list of actions to a list of functions that would return a bool if there was a difference in the value.
private readonly List<Func<Data, bool>> _updates;
And then the properties would look like this:
public int Rating
{
set
{
_updates.Add(data => {
if (data.Rating != value)
{
data.Rating = value;
return true;
}
return false;
});
}
}
And the try update method...
public bool TryUpdateFromMe(Data original)
{
if (_updates.Count == 0)
return false;
bool changesRequired = false;
foreach (var update in _updates)
{
changesRequired |= update.Invoke(original);
}
return changesRequired;
}
As you can see that property set implementation is rather clunky and would make the code nasty to read.
I'd like a way of extracting the check this property value then update it to another method that I can reuse in each property - I assume this is possibly somehow but it might not be.
Of course, if you have better suggestions for how to handle the PATCH situation then I'd be happy to hear them as well.
Thanks for reading this far.

Using { get set } Accessors for Multiple Values in MVC

EDIT: Question Reconstructed.
OK, I have revisited my get and set methods, but I am still very unclear on how it all works.
What I want to achieve is the Model is populated by the Controller, from the values that it takes form the form. This is then sent to the Db_Facade, which compares the uName and uPwd, and if they are equal returns the ACCESS, which will be set for the entire scope of the program.
I don't know if the get and set declarations are done correctly, or if they can be bunched together (If this is possible it would be great because I will be using this for much larger collections of data), and I'm pretty sure I'm implementing them wrong as well.
If you can help, my knowledge of Accessors is incredibly limited.
Here is my Compare Login method in my Controller:
public static void Compare_Login(User_Login_View Login_View)
{
User_Model getACCESS = new User_Model(); // Creates a new oject of User_Model
getACCESS.Name = Login_View.txtUsername.Text; //Populates the Model from the Login View
getACCESS.Pwd = Login_View.txtPassword.Text;
if (getACCESS.ACCESSLEVEL > 0)
{
Login_View.Close();
}
else
{
Login_View.lblError.Visible = true;
}
Login_View.Menu.SetMenuView();
}
Here is my Model:
public class User_Model
{
public string Name
{
get
{
return Db_Facade.uName;
}
set
{
Db_Facade.uName = value;
}
}
public string Pwd
{
get
{
return Db_Facade.uPwd;
}
set
{
Db_Facade.uPwd = value;
}
}
public int ACCESSLEVEL
{
get
{
return Db_Facade.ACCESS;
}
set
{
Db_Facade.ACCESS = value;
}
}
}
Here is the dummy database comparison:
class Db_Facade
{
public static string uName;
public static string uPwd;
public static string cPwd;
public static int ACCESS;
public static void getLoginACCESS()
{
uName = "paul";
uPwd = "pwd";
ACCESS = 1;
/* I get a "getACCESS does not exist" error here
if (uName == getACCESS.Name && uPwd == getACCESS.Pwd)
{
getACCESS.ACCESSLEVEL = ACCESS;
}
else
{
getACCESS.ACCESSLEVEL = 0;
}
*/
}
}
I don't know if it's needed, but here is my View
public partial class User_Login_View : Form
{
public Menu_View Menu { get; set; }
public User_Login_View()
{
InitializeComponent();
}
private void btnLogin_Click(object sender, EventArgs e)
{
User_Controller.Compare_Login(this);
}
}
2 Questions / Hints
1.) Where do you call your getLoginACCESS() ?
2.) Why do you think Db_Facade is able to access getACCESSfrom your class User_Controller?
a solution would be to modyfie your getLoginACCESS() to getLoginACCESS(User_Model getACCESS) and than call it in your Compare_Login(User_Login_View Login_View) befor your if like Db_Facade.etLoginACCESS(getACCESS);

c# properties, have a get with an auto-implemmented private set

Using c# auto-implemented properties can I have a class that does the following (psuedo C# code because I get an error - which is below when trying to compile this):
public class Foo {
public String HouseName { get; private set; }
public int HouseId { get; private set; }
public int BedsTotal {
get { return (BedsTotal < 0) ? 0 : BedsTotal; }
private set;
}
}
Error 5 'House.BedsTotal.set' must declare a body because it is not marked abstract, extern, or partial c:\src\House.cs
To me it seems like I should be able to get a body for the getter and rely on the private set being auto-generated like it would be if I did a { get; private set; } but that's not working.
Do I need to go the whole way and set up member variables, take the private setter off, and use the members vars instead?
Thanks!
Yes, you'll need to set up private variables because at the moment you will end up in a loop trying to read the get {} portion because it references itself.
Set up a private backing variable like this:
private int _bedsTotal;
public int BedsTotal {
get { return (_bedsTotal < 0) ? 0 : _bedsTotal; }
private set { _bedsTotal = value; }
}
Then you can access beds through the private setter
i whould go for an even more easier approach
private int _bedsTotal;
public int BedsTotal
{
get
{
return (this._bedsTotal < 0) ? 0 : this._bedsTotal;
}
private set
{
this._bedsTotal = value;
}
}
and so you can set the value of BedsTotal like this : this.BedsTotal = [integer];, no need to used other private methods since you can make use of the set

Categories