Processing multiple values in each other's get property - c#

I am getting a StackOverflow exception on "return TimeOne".
The Timecheck method sets both values depending on their value at any given time. Is there a way to process both values at the outset based on each other?
class Name
{
private string _Timeone
public string TimeOne
{
get
{
return _Timeone
}
set
{
TimeCheck();
_Timeone = value;
}
}
private string _TimeTwo
public string TimeTwo
{
get
{
return _TimeTwo
}
set
{
TimeCheck();
_TimeTwo= value;
}
}
private void TimeCheck()
{
string WrongTime = "....";
if (TimeOne == WrongTime && TimeTwo == WrongTime )
TimeOne = TimeTwo = DateTime.Now.ToString();
else if (TimeOne == WrongTime) TimeOne = TimeTwo
else if TimeTwo == WrongTime) TimeTwo = TimeOne;
}
}
}

The issue is caused by your setters calling TimeCheck, which in turn calls the setters, which calls TimeCheck, ad nauseum.
Break that cycle.
Your TimeCheck function can be rewritten so it sets the backing fields instead of calling the setters:
private void TimeCheck()
{
string WrongTime = "....";
if (_TimeOne == WrongTime && _TimeTwo == WrongTime )
{
_TimeOne = _TimeTwo = DateTime.Now.ToString();
}
else if (_TimeOne == WrongTime)
{
_TimeOne = _TimeTwo;
}
else if (_TimeTwo == WrongTime)
{
_TimeTwo = _TimeOne;
}
}
This breaks the cycle. Your setter can now call TimeCheck without fear of being called back in an endless cycle.

You're getting a stack overflow exception because your setters are calling themselves recursively with no end condition, when you do TimeTwo = value; Instead, you can create a private backing property for each public property and use those in the getters and setters:
private string _timeOne;
private string _timeTwo;
public string TimeOne
{
get { return _timeOne; }
set
{
TimeCheck();
_timeOne = value;
}
}
public string TimeTwo
{
get { return _timeTwo; }
set
{
TimeCheck();
_timeTwo = value;
}
With your current implementation, each time you say TimeOne = value; the setter is being called again, which calls it again, and so on.
EDIT
I agree that TimeCheck() should not be called in the setters. Instead, I think it would be more appropriate to validate those values, and reset them if necessary, elsewhere. Maybe in a service of some sort, or whatever code is setting those properties to begin with.

Related

Adding a bool for each property

I'm building a c# class that works with two different data sources. It will load a data source and take a configuration set from a function. Then I want to do several tasks on all properties within the object.
for example.
public String StreetAddress
{
get { return _streetAddress; }
set
{
if (value.Length <= 64)
_streetAddress = value;
else
_streetAddress = value.Substring(0, 1024).Trim();
}
}
public String City
{
get { return _city; }
set
{
if (value.Length <= 128)
_city = value;
else
_city = value.Substring(0, 128).Trim();
}
}
public String State
{
get { return _state; }
set
{
if (value.Length <= 128)
_state = value;
else
_state = value.Substring(0, 128).Trim();
}
}
So that holds the data from one side. I was hoping to be able to store and set a change flag on each property. So if we take State for example. If the person is moved from Texas to Illinois I want to set a bool within that property to note the change then be able to loop over all changes before saving the object to the DB. But I don't see any way to assign another state variable within that property. Is the best way to write another object on top of this to control it or is there another more creative way to store multiple strings within the one property?
If you'd like an OOP way of doing the thing, you can:
Define an interface and a class for holding your property, such as:
interface IPropertySlot
{
bool IsDirty { get; }
void ResetIsDirty();
object UntypedValue { get; }
}
class PropertySlot<T>:IPropertySlot
{
public T Value { get; private set; }
public bool SetValue(T value)
{
if (!Equals(_value, Value))
{
Value = value;
IsDirty = true;
return true;
}
return false;
}
public bool IsDirty { get; private set; }
public void ResetIsDirty()
{
IsDirty = false;
}
public object UntypedValue
{
get { return Value; }
}
}
Store your properties inside your class in a dictionary from String (for name of property) to IPropertySlot and get/set them through a pair of methods:
void SetProperty<T>(string name, T value)
{
IPropertySlot property;
if (!_properties.TryGetValue(name, out property))
{
property = new PropertySlot<T>();
_properties[name] = property;
}
((PropertySlot<T>)property) .SetValue(value);
}
T GetProperty<T>(string name)
{
IPropertySlot property;
if (!_properties.TryGetValue(name, out property))
{
property = new PropertySlot<T>();
_properties[name] = property;
}
return ((PropertySlot<T>)property).Value;
}
Finding the changed properties later is just a matter of going over the _properties.Values and finding which of them are IsDirty.
This approach also gives you a way to add more functionality to your properties in an OO manner (such as raising PropertyChanged/PropertyChanging events, mapping it to DB fields, etc.).
In such a situation I'd prefer an approach external to the Dto implementation.
Implement some unit that would take two instances of a class, and determine all the differences.
Map each property to compare:
static PropertyManager<Dto> manager = new PropertyManager<Dto>()
.Map(x => x.City)
.Map(x => x.StreetAddress);
Use two instances to compute difference:
var a = new Dto{ StreetAddress = "Foo", City = "Bar" };
var b = new Dto{ StreetAddress = "Foo", City = "Baz" };
var differences = manager.ComputeDifferences(a,b).ToList();
if( differences.Any() )
{
Console.WriteLine("Instances differ");
}
foreach (var diff in differences)
{
Console.WriteLine(diff);
}
This sample code prints out:
Instances differ
x.City
Here is a complete code example:
https://dotnetfiddle.net/4sNeoN

Retaining enum values in asp.net

I have an asp.net page, wherein i am using enums (with Properties defined in class file in app_code)
Now my problem is whenever page gets postbacks the value of the enum in property gets resetted to the first one
I even tried setting the property as static, but still that didn't helped. below is my enum and property declaration:
private static UrlType _type;
public static UrlType UrlPattern
{
get
{
HttpContext.Current.Response.Write("GET: " +_type + "<br>");
return _type;
}
set
{
_type = value;
HttpContext.Current.Response.Write("SET : " +_type + "<br>");
}
}
public int VanityId { get; set; }
public enum UrlType
{
ArticleOnly,
ArticleCategoryCombination,
Normal,
TechForum
}
and this is how i calls:
public void BindRewrite()
{
GrdRewrite.DataSource = objVanity.GetAllRewriteVanities(Vanity.UrlPattern);
GrdRewrite.DataBind();
if (Vanity.UrlPattern == Vanity.UrlType.ArticleCategoryCombination)
{
GrdRewrite.Columns[2].Visible = false;
GrdRewrite.Columns[3].Visible = GrdRewrite.Columns[5].Visible = GrdRewrite.Columns[6].Visible = true;
}
else if (Vanity.UrlPattern == Vanity.UrlType.ArticleOnly)
{
GrdRewrite.Columns[5].Visible = true;
GrdRewrite.Columns[2].Visible = GrdRewrite.Columns[3].Visible = GrdRewrite.Columns[6].Visible = false;
}
else if (Vanity.UrlPattern == Vanity.UrlType.Normal)
{
GrdRewrite.Columns[2].Visible = true;
GrdRewrite.Columns[3].Visible = GrdRewrite.Columns[5].Visible = GrdRewrite.Columns[6].Visible = false;
}
}
protected void Page_Load(object sender, EventArgs e)
{
pnlAdmin.Visible = (objVanity.UserName == "host");
if (objVanity.UserName == "host")
Enable();
else
FieldsOpenForEditors(objVanity.SiteSupportUrlFormat);
if (!IsPostBack)
{
Vanity.GenerateListFromEnums(drpAdminUrlType);
if (objVanity.UserName == "host")
Vanity.UrlPattern = Vanity.UrlType.ArticleOnly;
else
Vanity.UrlPattern = objVanity.SiteSupportUrlFormat;
BindRewrite();
}
}
can anyone tell me how to retain the value of the enum across postbacks
i think viewstate could be option, but don't have any clue about how to store the enum value and restore the string value casted in enum.
If you want to persist a value between post back, you need to store it in Session, Cache or ViewState.
In your case, ViewState could be a prefer choice.
public UrlType UrlPattern
{
get
{
if (ViewState["UrlPattern"] != null)
return (UrlType)Enum.Parse(typeof(UrlType), ViewState["UrlPattern"].ToString());
return UrlType.Normal; // Default value
}
set
{
ViewState["UrlPattern"] = value;
}
}

return value only when it is available else wait for the value..... c#

Return the value only when it is available. if I use a condition to check the null condition it is throwing a exception. "saying not all code paths return a value"
internal PinMessage()
{
obj.PinsAvailable.ObserveOn(SynchronizationContext.Current).Subscribe(HandlePinsAvailable);
}
private void HandlePinsAvailable(byte[] pinBytes)
{
pinmesssage = Encoding.ASCII.GetString(pinBytes);
}
internal string GetPinMessage(string AccoutNumber)
{
string pinstring = string.Empty;
obj.SendPinRequest(AccoutNumber);
pinstring = pinmesssage;
return pinstring;
}
private string _pinMessage;
public string pinmesssage
{
get//Not all Code paths return a value
{
if (_pinMessage != null)
return _pinMessage;
}
set { _pinMessage = value; }
}
You are getting this compile error because you don't return anything in the case where _pinMesSafe is null. You need to return something from your Access or in the case when that is true, or throw an exception.
private string _pinMessafe;
public string pinmesssage
{
get {
if (_pinMessafe != null)
return _pinMessafe;
}
set { _pinMessafe = value; }
}
You have to return something when it's being called, you can't just put a method call on hold.
What you could do is force a check yourself:
private string _pinMessafe;
public string pinmesssage
{
get {
return _pinMessafe ?? GetMessage()
}
set { _pinMessafe = value; }
}
In this scenario, GetMessage() would have to take care of returning the message. It's hard to give a more detailed answer with the information you've provided.
You should edit your code to make it more readable (this includes the english spelling errors) and add info if needed.
This is not the "best" practice, but will work and let your consumer wait until the producer has written the variable.
private string _pinMessafe;
object locker = new object();
public string pinmesssage
{
get
{
string x = null;
while(x == null) {
lock(locker) { x = _pinMessafe ; }
Thread.Sleep(1);
}
return x;
}
set { lock(locker) { _pinMessafe = value; } }
}

how to make read only property available in my usercontrol

i make user control from 3 text boxes but i don not how to declare read only property to it i tried many things but it do not work here is my code to make the control
i want to make it read only when needed like if i add checkbox i want if checkbox.check=true make my control readonly
public partial class dateIN : UserControl
{
Dates datess = new Dates();
public dateIN()
{
InitializeComponent();
}
private void dateIN_Leave(object sender, EventArgs e)
{
if (txtDay.Text != "" || txtMonth.Text != "" || txtYear.Text != "")
{
if (!datess.IsHijri(txtDay.Text.Trim() + "/" + txtMonth.Text.Trim() + "/" + txtYear.Text.Trim()))
{
txtDay.Focus();
}
}
}
public string Day
{
set { txtDay.Text = value; }
get { return txtDay.Text; }
}
public string Month
{
set { txtMonth.Text = value; }
get { return txtMonth.Text; }
}
public string Year
{
set { txtYear.Text = value; }
get { return txtYear.Text; }
}
need to know how to make read only property available here plz
just remove the set { } part of the property
Example:
public string Day
{
get { return txtDay.Text; }
}
I dont know the correlation of where your "txtDay", "txtMonth", "txtYear" come from, but you could do something like
public partial class dateIN : UserControl
{
...
...
private bool AllowEditing()
{ return SomeCondition when SHOULD be allowed...; }
public string Day
{
// only allow the set to apply the change if the "AllowEditing" condition
// is true, otherwise, ignore the attempt to assign.
set { if( AllowEditing() )
txtDay.Text = value; }
get { return txtDay.Text; }
}
// same concept for month and year too
}
so may you add some flag to your set when it is true then you set a value.
also you can work with textbox property called ReadOnly.

I am getting into infinite loop in property setter

public int Position
{
get
{
if (Session["Position"] != null)
{
Position = Convert.ToInt32(Session["Position"]);
}
else
{
Position = 5;
}
return Position;
}
set
{
Position = value;
}
}
my program calls the get and goes into if loop and then runs infitely into set code
The error is because in your set {} you are invoking the same setter recursively.
Correct code would be
private int _position;
public int Position
{
get
{
if (Session["Position"] != null)
{
this._position = Convert.ToInt32(Session["Position"]);
}
else
{
this._position = 5;
}
return this._position;
}
set
{
this._position = value;
}
}
Use a member variable or perhaps store it in the session.
private int _position;
public int Position
{
get
{
if (Session["Position"] != null)
{
_position= Convert.ToInt32(Session["Position"]);
}
else
{
_position= 5;
}
return _position;
}
set
{
_position = value;
}
}
There's nothing particularly string-like about session state items.
Why wouldn't you just follow the KISS principle and do something like
public int Position
{
get { return (int) ( Session["Position"] ?? 5 ) ; }
set { Session["Position"] = value ; }
}
or (depending on your actual requirements/specs:
public int Position
{
get { return Session["Pointer"] as int? ?? position ?? 5 ; }
set { position = value ; }
}
private int? position ; // backing store
An auto-implemented property property consists of a getter, a setter and a backing field. If you write the code yourself, a field might not be necessary.
Your getter invokes setter, and the setter invokes setter; that would be infinite recursion. You might need a field for storing Position.
However, if we change it with storing to a field, and the setter in fact doesn't effect. So, the code could be changed to:
public int Position {
set {
}
get {
int x;
return (x=Convert.ToInt32(Session["Position"]))>0?x:5;
}
}
You don't need to check for null, Convert.ToInt32(null) is zero.

Categories