Recently I've found myself more and more getting into the habit of passing things by reference. I've always been taught that passing by ref is 'usually' a bad idea, as it's trickier to keep track of what could be affecting your objects, so I wanted to post the question: 'What are the cons of passing by reference?'
An example of where I've recently been passing by reference, is lazy-instantiated objects within the viewstate. Within my code-behind I have a private field, with a public property, that utilises a helper method. Current implement is as follows:
ASPX Code-behind
/// <summary>
/// Private field member for MyObject
/// </summary>
private Foobar _myObject = null;
/// <summary>
/// Gets or sets the current object
/// </summary>
public Foobar MyObject
{
get
{
return this.ViewState.GetValue("MyObject", new Foobar(), ref this._myObject);
}
set
{
this.ViewState.SetValue("MyObject", value, ref this._myObject);
}
}
This aims to replace lots of repetitious if
assignment checks against fields and lazy-instantiated objects within a class. For example, without the helper class it would be something similar to.
/// <summary>
/// Private field member for MyObject
/// </summary>
private Foobar _myObject = null;
/// <summary>
/// Gets or sets the current object
/// </summary>
public Foobar MyObject
{
get
{
if (this._myObject != null)
{
return this._myObject;
}
var viewStateValue = this.ViewState["MyObject"];
if (viewStateValue == null || !(viewStateValue is Foobar))
{
this.ViewState["MyObject"] = new Foobar();
}
return this._myObject = (Foobar)this.ViewState["MyObject"];
}
set
{
this._myObject = value;
this.ViewState["MyObject"] = value;
}
}
Both snippets of code are achieving the same. The first approach is centralising everything, which is a good thing, however it is passing by reference, which in this instance I'm not sure is a good idea?
Any advice and / or experiences is greatly appreciated.
Edit
The GetValue
and SetValue
are extension methods on the ViewState. Code is supplied below.
/// <summary>
/// Gets a value from the current view state, if the type is correct and present
/// </summary>
public static T GetValue<T>(this StateBag source, string key, T @default)
{
// check if the view state object exists, and is of the correct type
object value = source[key];
if (value == null || !(value is T))
{
return @default;
}
// return the object from the view state
return (T)source[key];
}
/// <summary>
/// Sets the key value within the view state
/// </summary>
public static void SetValue<T>(this StateBag source, string key, T value)
{
source[key] = value;
}
/// <summary>
/// Gets a value from the reference field helper, or the current view state, if the type is correct and present
/// </summary>
/// <returns>Returns a strongly typed session object, or default value</returns>
public static T GetValue<T>(this StateBag source, string key, T @default, ref T fieldHelper)
{
return fieldHelper != null ? fieldHelper : fieldHelper = source.GetValue(key, @default);
}
/// <summary>
/// Sets the key value within the view state and the field helper
/// </summary>
/// <param name="value">The value</param>
public static void SetValue<T>(this StateBag source, string key, T value, ref T fieldHelper)
{
source[key] = value;
fieldHelper = value;
}