Possible solution for problem with using StackTrace in inlined release code

Possible solution for problem with using StackTrace in inlined release code

Old forum URL: forums.lhotka.net/forums/t/1302.aspx


Brelo posted on Friday, September 22, 2006

As stated in http://groups.msn.com/CSLANET/general.msnw?action=get_message&mview=0&ID_Message=26513 the StackTrace in release code does not always get the expected function name because of inlining, e.g. the PropertyHasChanged() method will fail to get the property name if the code of the property is inlined by the compiler.

One solution would be to mark the set accessor with the MethodImpl(MethodImplOptions.NoInlining) attribute, eg.

   public string Name
   [MethodImpl(MethodImplOptions.NoInlining)]
   set
   {
     _name = value;
     PropertyHasChanged();
   }

But this has the disadvantage that the programmer could forget to write the attribute.

Of course, the second solution is to use the PropertyHasChanged(string) overload. But this has the disadvantage, that when the programmer decides to change the property's name afterwards, she could forget to change the actual string parameter value of PropertyHasChanged, getting no compiler error for that.

So I propose to discard the flawy PropertyHasChanged() method and replace it with the following (of course a breaking change):

    protected void PropertyHasChanged(System.Reflection.MethodBase propertyAccessor)
    {
      string propertyName = propertyAccessor.Name.Substring(4);
      PropertyHasChanged(propertyName);
    }

In the property accessor you are calling it as follows:

   public string Name
   set
   {
     _name = value;
     PropertyHasChanged(MethodBase.GetCurrentMethod());
   }

So this has the advantage of having to write the property name only once. The programmer has to type about as much code as in solution one, but can't forget anything, because the method signature forces him to fill in the MethodBase call. The other CSLA methods using StackTrace could be refactored in this way, as well.

As far as I know MethodBase.GetCurrentMethod() always returns the excpected function name, even in optimized release code. I don't know if this is always true, someone at Microsoft can tell?. It seems that the use of MethodBase.GetCurrentMethod() prevents implictly the inlining of the method in which it is called.

 

Brian Criswell replied on Friday, September 22, 2006

So why not do:

public string
Name
{
    set
    {
        CanWriteProperty(
MethodBase.GetCurrentMethod().Name.Substring(4), true);
        if (value == null) value = string.Empty;

        if (_name != value)
        {
            _name = value;
            PropertyHasChanged(MethodBase.GetCurrentMethod().Name.Substring(4));
        }
    }
}

and work within the framework?  The snippets include the no-inlining attribute, and a lot of people use code generators that change the property name and the PropertyHasChanged text simultaneously.


Copyright (c) Marimer LLC