tags:

views:

60

answers:

3

I just saw this line of C# code and I am wondering if it is expensive

Assembly assembly = useEntryAssembly ? Assembly.GetEntryAssembly() : Assembly.GetCallingAssembly();
+3  A: 

Unless you perform calls like that a lot, the expensiveness is rather minuscule and I wouldn't worry about it.

On my machine Assembly.GetEntryAssembly() takes 164 ticks the first time and 7 the next on a random run in debug mode. Without diving too deep in with Reflector it seems to be caching the calls.

There are 2597734 ticks a second on my machine, so 164 vs 7 is still unimportant.

Mikael Svenson
It depends if the .NET framework is already caching. Does it?
Stefan Steinegger
It caches. Assembly.GetEntryAssembly(); takes 164 ticks the first time I run it and 7 the next. And there are 2597734 ticks a second on my machine, so 164 vs 7 is still unimportant.
Mikael Svenson
A: 

I don't know about performance, but it's a code smell depending on what you're going to use this Assembly object for.

Since you can do typeof(Anything).Assembly to find an assembly, you already know what assembly you're in without calling these. The typeof keyword can be checked by the compiler, whereas the results of GetEntryAssembly and GetCallingAssembly can surprise you. (For instance, GetEntryAssembly can be null.)

It would help to know what information you need from this assembly - there could be a better way to retrieve it.

Tim Robinson
The OP's code is not getting the current executin assembly, it is getting either the entry assembly (the top level one on the call stack), or the calling one (the one immediately prior on the callstack)
Rob Levine
I understand the OP's code, but the intention isn't clear. Often your code knows enough to be able to obtain an `Assembly` in a way that the compiler can check: that is, from `typeof`. There are relatively few cases where your code genuinely know so little that it can only call `GetEntryAssembly` or `GetCallingAssembly`.
Tim Robinson
@Tim - I don't agree. All my utility classes (for example) are called by all sorts of other classes in other assemblies. There are *some* classes where I know it in only used in one calling context, but it certainly isn't the norm for me to assume this.
Rob Levine
In which case it's useful to make the methods generic or pass a `Type` through. In particular, the presence of a `Type` parameter in a function serves as a hint that that function will be doing reflection. Having a method depend on the calling assembly tends to blow up during unit testing, where the calling assembly is often a dynamically-generated mock assembly.
Tim Robinson
@Tim - totally agree with your point about compiler checking, but in this case (without knowing more about the actual use case), given the actual assemblies being reflected on, it may well be the right way to go. For all we know, this could be part of a logging class or something, in which case this seems a reasonable approach to me.
Rob Levine
+1  A: 

Unless you make these calls a lot, I wouldn't worry. In any case, there are some simple optimisations you could make.

For example, Assembly.GetEntryAssembly() won't change during the lifetime of your process (for a given AppDomain), so there is no need to do this call repeatedly, even if you need to access it. You could replace it with:

private static Assembly _entryAssembly;

private Assembly ExecutingAssembly
{
  get 
  { 
    if (_entryAssembly == null )
    {
      _assembly = Assembly.GetEntryAssembly();
    }
    return _entryAssembly
}

Now you don't have to worry how expensive this call is; although possibly, as a commenter on another answer remarks, maybe the framework actually does this for you.

[note: this is intentionally not a thread safe singleton - the worst case scenario is that you make the call to Assembly.GetEntryAssembly() a few times if first accessed similtaneously by several thread - not worth trying to lock for this scenario IMHO]

Rob Levine