Generics, Casting and Anonymous Delegates and the Where clause
/I have a situation where the code looks like:
( ( TextBox ) ( _someParentControl.FindControl( "_childControlId" ) ) ).Text = "SomeText";
( ( TextBox ) ( _someParentControl.FindControl( "_childControlId" ) ) ).Enabled = someBool;
repeat about 10 times with different child control type, parent controls, child Ids, and properties.
obviously, there's a similarity and refactoring was in order.
private static void ExecuteOnControl<T>( WebControl parent, string id, Action<T> action) where T : WebControl
{
T control = parent.FindControl( id ) as T;
if (control != null && action != null)
{
action( control );
}
}
The where clause is important because you can't cast "As" within the function without having some limits on the generc T.
Which allowed me to shrink the example down to:
ExecuteOnControl<TextBox>(_parentControl, "_childControlId", delegate(TextBox tb) { tb.Text = "someText"; });
This can be further simplified since the delegate can be declared once and used later.
Action<TextBox> tbDel = delegate(TextBox tb) { tb.Text = "someText"; };
ExecuteOnControl<TextBox>(_parentControl, "_childControlId1", tbDel);
ExecuteOnControl<TextBox>(_parentControl, "_childControlId2", tbDel);
One can argue here that the new code isn't really that much more readable though, but it was good hacking
( ( TextBox ) ( _someParentControl.FindControl( "_childControlId" ) ) ).Text = "SomeText";
( ( TextBox ) ( _someParentControl.FindControl( "_childControlId" ) ) ).Enabled = someBool;
repeat about 10 times with different child control type, parent controls, child Ids, and properties.
obviously, there's a similarity and refactoring was in order.
private static void ExecuteOnControl<T>( WebControl parent, string id, Action<T> action) where T : WebControl
{
T control = parent.FindControl( id ) as T;
if (control != null && action != null)
{
action( control );
}
}
The where clause is important because you can't cast "As" within the function without having some limits on the generc T.
Which allowed me to shrink the example down to:
ExecuteOnControl<TextBox>(_parentControl, "_childControlId", delegate(TextBox tb) { tb.Text = "someText"; });
This can be further simplified since the delegate can be declared once and used later.
Action<TextBox> tbDel = delegate(TextBox tb) { tb.Text = "someText"; };
ExecuteOnControl<TextBox>(_parentControl, "_childControlId1", tbDel);
ExecuteOnControl<TextBox>(_parentControl, "_childControlId2", tbDel);
One can argue here that the new code isn't really that much more readable though, but it was good hacking