So I have a to call a method quite regularly as part of a pattern. It looks like something like this:
DoWork(new TimeSpan(0, 0, 2, 0));
Or in another part of the code:
DoWork(new TimeSpan(0, 0, 6, 50));
In each case the parameter never changes and I recently woke up and worked out what a performance whack it is to keep creating the parameter for every call. The solution I have is this:
// instance field
TimeSpan _cachedValue = new TimeSpan(0, 0, 2, 0);
// and when called,
DoWork(this._cachedValue)
This is all pretty obvious, the issue I have with it though is storing the parameter value in a field... its messy - in an already bloated class (In one class for example I'd call the do work method with 10 or so variants many thousands of times each - so thats ten extra fields).
It would be cool however if I could do something like this:
DoWork([DoesNotChange()]new TimeSpan(0, 0, 2, 0));
This theoretical attribute on the parameter would indicate that for that particular call the value only ever needs to be worked out once, and then passed to method repeatedly.
So is anything like this possible? Or am I just off my nut?
Cheers
EDIT:
Wow you folks work fast, thanks. As for my question, I should of learnt last time not to over simplify - sorry. I'm going to post an actual code snippet for clarity. This class is used for databinding in a Silverlight app. I'm using strong typing for PropertyChanged events for maintainability:
internal class BasicDataClass : INotifyPropertyChanged
{
private readonly Expression<Func<double>> _propertySelector;
private double _someFieldA;
private double _someFieldB;
private double _someFieldC;
public BasicDataClass()
{
_propertySelector = () => SomeFieldC;
}
/// <summary>
/// This is fastest
/// </summary>
public double SomeFieldA
{
get { return _someFieldA; }
set
{
if (!_someFieldA.Equals(value))
{
_someFieldA = value;
PropertyChanged.Raise(this, "SomeFieldA");
}
}
}
/// <summary>
/// This is many times slower
/// </summary>
public double SomeFieldB
{
get { return _someFieldB; }
set
{
if (!_someFieldB.Equals(value))
{
_someFieldB = value;
PropertyChanged.Raise(() => SomeFieldB);
}
}
}
/// <summary>
/// This is only, very slightly slower than A
/// but requires an extra field
/// </summary>
public double SomeFieldC
{
get { return _someFieldC; }
set
{
if (!_someFieldC.Equals(value))
{
_someFieldC = value;
PropertyChanged.Raise(_propertySelector);
}
}
}
#region INotifyPropertyChanged Members
/// <summary>
/// The property changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
And for reference, the Raise extension methods:
public static void Raise<TValue>(
this PropertyChangedEventHandler handler, Expression<Func<TValue>> propertySelector)
{
if (handler != null)
{
var memberExpression = propertySelector.Body as MemberExpression;
if (memberExpression != null)
{
object sender = ((ConstantExpression)memberExpression.Expression).Value;
handler(sender, new PropertyChangedEventArgs(memberExpression.Member.Name));
}
}
}
public static void Raise(this PropertyChangedEventHandler handler, object sender, string propertyName)
{
if (handler != null)
{
handler(sender, new PropertyChangedEventArgs(propertyName));
}
}
Again, sorry for not being specific.