1

This question is related to How to detect static code dependencies in C# code in the presence of constants?

If type X depends on a constant defined in type Y, this dependency is not captured in the binary code, because the constant is inlined. Yet the dependency is there - try compiling X without Y and the compilation fails. So it is a compile time dependency, but not runtime.

I need to be able to discover such dependencies and scanning all the source code is prohibitively expensive. However, I have full control over the build and if there is a way to instruct the C# compiler not to inline constants - that is good enough for me.

Is there a way to compile C# code without inlining the constants?

EDIT 1

I would like to respond to all the comments so far:

  1. I cannot modify the source code. This is not a toy project. I am analysing a big code base - millions of lines of C# code.
  2. I am already using Roslyn API to examine the source code. However, I only do it when the binary code inspection (I use Mono.Cecil) of a method indicates the use of dynamic types. Analysing methods using dynamic with Roslyn is useful, because not all the dynamic usages are as bad as reflection. However, there is absolutely no way to figure out that a method uses a constant in general. Using Roslyn Analyser for that takes really long time, because of the code base size. Hence my "prohibitively expensive" statement.
  3. I have an NDepend license and I used it at first. However, it only processes binary code. It does NOT see any dependencies introduced through constants. My analysis is better, because I drill down to dynamic users and employ Roslyn API to harvest as much as I can from such methods. NDepend does nothing of the kind. Moreover, it has bugs. For example, the latest version does not inspect generic method constraints and thus does not recognise any dependencies introduced by them.
mark
  • 59,016
  • 79
  • 296
  • 580
  • Is making it _not_ a constant an option? – mjwills Sep 04 '21 at 04:57
  • A [Roslyn Code Analzyer](https://learn.microsoft.com/en-us/visualstudio/code-quality/roslyn-analyzers-overview) could be useful. – Klaus Gütter Sep 04 '21 at 06:03
  • 2
    _"is a way to instruct the C# compiler not to inline constants"_ - possibly useful (my emphasis): _["When you use a `const` string, the compiler **embeds** the string's value at compile-time...A `static readonly` string is a normal field that gets **looked up at runtime**. Therefore, if the field's value is changed in a different assembly, the changes will be seen as soon as the assembly is loaded, without recompiling"](https://stackoverflow.com/a/3190930/585968)_ –  Sep 04 '21 at 06:51
  • _"...scanning all the source code is prohibitively expensive..."_ - you might want to check out the static code analysis tool [nDepend](https://www.ndepend.com/). With it you can get metrics on your code, perform LINQ like searches and even write external tooling –  Sep 04 '21 at 06:53
  • It's not just that you can't tell it not to inline constants, it is simply not valid in IL to do something like `ldsfld OtherClass.YourConstant` so there is no way for the compiler to do this, it *must* inline. – Charlieface Sep 05 '21 at 00:13
  • Probably the only feasible option is to roll out your own compiler (fork Roslyn and remove constant inlining from it). – Lex Li Sep 05 '21 at 00:52
  • @LexLi - hypothetically speaking, if someone would consider doing it, is it at all possible given the comment from Charlieface – mark Sep 05 '21 at 15:01
  • @mark Your forked compiler can simply convert all `const` to `readonly static` during compilation (without modifying the original source code). It is up to you to choose what kind of MSIL to generate, so you are not limited by what Roslyn originally does. – Lex Li Sep 05 '21 at 15:09

0 Answers0