Getting Started with Adobe After Effects - Part 6: Motion Blur


Upload Image Close it
Select File

Slaks Blog
Browse by Tags · View All
.Net 39
C# 28
functions 10
C# 5 9
caller-info-attributes 9
Javascript 9
delegates 8
closures 8
design 8
ASP.Net MVC 7

Archive · View All
July 2011 10
September 2011 10
June 2011 10
October 2011 8
November 2011 4
December 2011 4
May 2011 2
August 2011 2
June 2012 1
April 2011 1

Subtleties of C# 5’s new [CallerLineNumber]

Oct 7 2011 12:00AM by SLaks   

This is part 2 in a series about C# 5’s new caller info attributes; see the introduction.

The [CallerLineNumber] attribute tells the compiler to use the line number of the call site instead of the parameter’s default value.  This attribute has more corner cases than [CallerFileName].  In particular, unlike the C preprocessor’s __LINE__ macro, the C# compiler inserts the line number of a parsed method call.  Therefore, it is not always clear which line a method call expression maps to.

What should this call print:

static class Utils {
    int GetLine([CallerLineNumber] int line = 0) {
        return line;
    }
}

Console.WriteLine(
    Utils
        .
        GetLine
        (
        )
    );

Should it print the line number that the statement started? The line in which the call to GetLine started? The line containing the parentheses for GetLine? What if it’s in a multi-line lambda expression?

There are also a few cases in which methods are called implicitly by the compiler without appearing in source code.  What should this code print?

class Funny {
    public Funny Select(Func<object, object> d,
                        [CallerLineNumber]int line = 0) {
        Console.WriteLine(line + ": " + d(d));
        return this;
    }
}

var r = (from x in new Funny() 
         let y = 1 
         select 2);

This code contains two implicit calls to the Select method that don’t have a clear source line (it gets worse for more complicated LINQ queries)

In fact, it is possible to have an implicit method call with no corresponding source code at all.

Consider this code:

class Loggable {
    public Loggable([CallerLineNumber] int line = 0) { }
}
class SomeClass : Loggable { }

The compiler will implicitly generate a constructor for SomeClass that calls the base Loggable constructor with its default parameter value.  What line should it pass? In fact, if SomeClass is a partial class that is defined in multiple files, it isn’t even clear what [CallerFileName] should pass.

Also, what should happen in the unlikely case that a [CallerLineNumber] method is called on line 3 billion (which would overflow an int)? (This would be easier to test on Roslyn with a fake stream source) Should it give an integer overflow compile-time error?  If [CallerLineNumber] also supports byte and short parameters, this scenario will be more likely to happen in practice.

Next time: [CallerMemberName]


Republished from SLaks.Blog [36 clicks].  Read the original version here [1 clicks].

SLaks
149 · 1% · 327
0
Liked
 
0
Lifesaver
 
0
Refreshed
 
0
Learned
 
0
Incorrect



Submit

Your Comment


Sign Up or Login to post a comment.

    Copyright © Rivera Informatic Private Ltd Contact us      Privacy Policy      Terms of use      Report Abuse      Advertising      [ZULU1097]