Home > front end >  In C# how can I execute a method on an object when I am using that object as a parameter?
In C# how can I execute a method on an object when I am using that object as a parameter?

Time:11-28

This is on an asp.net webforms application using .net Framework v4.8

(I know that this is old technology and I should not be coding new projects in it. I haven't written anything in asp.net in over ten years, and when I coded this way, webforms was the thing to use. I will learn Blazor and recode this in a more modern platform in the future. Sorry, I am just trying to head off any "why are you using webforms" in the comments.)

I have a parameter on a page that looks like this:

        public Dictionary<string, string> StrategySubtypes {
        get
        {
            return (ViewState["StrategySubtypes"] == null) ? new Dictionary<string, string>() : (Dictionary<string, string>)ViewState["StrategySubtypes"];
        }
        set
        {
            ViewState["StrategySubtypes"] = value;
        }
    }

When I call the add method on the dictionary using the code below, the code does not return an error, but it also does not write the new dictionary item into the ViewState.

        protected void btnAddSubtype_Click(object sender, EventArgs e)
    {
        Dictionary<string, string> tmpStrategySubtypes = StrategySubtypes;
        StrategySubtypes.Add(txtSubtype.Text, "new");
        lbSubtypes.DataSource = StrategySubtypes;
        lbSubtypes.DataTextField = "Key";
        lbSubtypes.DataValueField = "Value";
        lbSubtypes.DataBind();
        txtSubtype.Text = String.Empty;
    }

It just sort of goes into the ether. I believe what is happening is that when I call the Add method, I am getting the Dictionary from the get accessor and I am executing the add method on that dictionary, but Add does not call the set accessor so I'm just Databinding against the same original Dictionary.

I'm working around this with the following code

        protected void btnAddSubtype_Click(object sender, EventArgs e)
    {
        Dictionary<string, string> tmpStrategySubtypes = StrategySubtypes;
        tmpStrategySubtypes.Add(txtSubtype.Text, "new");
        StrategySubtypes = tmpStrategySubtypes;
        tmpStrategySubtypes.GetEnumerator().Dispose();
        lbSubtypes.DataSource = StrategySubtypes;
        lbSubtypes.DataTextField = "Key";
        lbSubtypes.DataValueField = "Value";
        lbSubtypes.DataBind();
        txtSubtype.Text = String.Empty;
    }

But this seems inelegant, and clunky. There must be a better, more correct way to achieve this. My question is, if I am using an object as a public parameter, is there a way to call a method directly on that parameter and have it store the results with the set accessor?

CodePudding user response:

In the get accessor, in case of null, the current code creates a new dictionary but it never sets the ViewState with this new dictionary instance. So when you ask again the value for the StrategySubtypes property the null is still there and a new dictionary is returned.
Easy fix:

public Dictionary<string, string> StrategySubtypes {
get
{
    var dict = ViewState["StrategySubtypes"] as Dictionary<string, string>;
    if(dict == null)
    {
       dict = new Dictionary<string, string>();
       ViewState["StrategySubtypes"] = dict;
    }
    return dict;
}
set
{
    ViewState["StrategySubtypes"] = value;
}
  • Related