1

I create a CSharpCodeProvider like so:

CSharpCodeProvider  codeProvider        = new CSharpCodeProvider(new Dictionary<string, string>{{ "CompilerVersion", "v4.0" }});
CompilerParameters  compileParameters   = new CompilerParameters(refs.ToArray(), newFile, debugBuild) { WarningLevel = 4 };

I have a script that creates the WPF FormattedText object likes so:

FormattedText volumeText = new FormattedText(volumeString, Core.Globals.GeneralOptions.CurrentCulture, FlowDirection.LeftToRight, typeFace, SuperDom.Font.Size, ForeColor) { MaxLineCount = 1, MaxTextWidth = renderWidth - 6, Trimming = TextTrimming.CharacterEllipsis };

.NET 4.6.2 added a new constructor for specifying DPI scaling and the current method we use is deprecated. However, our application targets .NET 4.5.0, and this is all we support. However, when compiling my code, I still get the following warning:

Warning: 'System.Windows.Media.FormattedText.FormattedText(string, System.Globalization.CultureInfo, System.Windows.FlowDirection, System.Windows.Media.Typeface, double, System.Windows.Media.Brush)' is obsolete: 'Use the PixelsPerDip override'

There is no valid use case (for us) where the new constructor is valid, and in fact what I would expect if someone tried to use it is to get a compile error due to that method signature being incorrect for 4.5.

Is there a way to avoid these warnings? Previously we did not specify the CompilerVersion for the code provider, but adding it did not help, and based on what I've seen in other questions here, v4.0 is the only valid version to use for my case anyway. Would a different warning level avoid this?

Sean Beanland
  • 1,098
  • 1
  • 10
  • 25
  • 1
    [This question](http://stackoverflow.com/questions/20018979/how-can-i-target-a-specific-language-version-using-codedom) details how to target a different framework with CodeDom. No idea if the same approach applies today and with the 4.5 framework, but that is your issue, not the compiler version. – Jeroen Mostert Oct 28 '16 at 15:16
  • Hmya, you are not actually targeting 4.5. You can intentionally target an old .NET version on your dev machine thanks to the "developer packs" that VS installs. Doesn't work for System.CodeDom, your client won't have them available. You get whatever version is installed on the client's machine, that's unpredictable. Indeed plays havoc with FormattedText, you can't depend on the overloads that take the *pixelsPerDip* argument either. No clean fix, you'll have to eat that warning. – Hans Passant Oct 28 '16 at 15:51
  • @HansPassant My project targets .NET 4.5. If I try to use the overload introduced in .NET 4.6.2 in my own code, I get a compile error. This is what I want to happen when compiling a script, rather than getting the deprecated warning above. – Sean Beanland Oct 28 '16 at 15:55
  • FYI [support for 4.5 ended in January](https://blogs.msdn.microsoft.com/dotnet/2015/12/09/support-ending-for-the-net-framework-4-4-5-and-4-5-1/), you should really be looking at 4.5.2 – lgaud Oct 28 '16 at 18:43
  • @lgaud Understood, but unfortunately it's not up to me – Sean Beanland Oct 28 '16 at 18:44

1 Answers1

2

The way Visual Studio handles this is by not using the system assemblies during compilation. Instead, a set of reference assemblies is used, which contains the correct classes and methods, but without implementations. The reference assemblies for 4.5 and 4.6 can be different, so particular attributes that were added in 4.6 won't be seen when targeting the 4.5 reference assemblies. Unless those reference assemblies are available on the runtime system, there won't be a way to avoid the warnings, other than suppressing them, e.g. using #pragma.

But if the compilation happens on the runtime system, then I have to disagree with your assertion:

However, our application targets .NET 4.5.0, so the new way of doing things is irrelevant.

You're compiling your script against the .NET 4.6 assemblies, so the new way of doing things is very relevant. If you're compiling on the runtime system, you can dynamically detect whether the new constructor is available, and if so, use that. Your application may be built targeting .NET 4.5, but your script isn't, or at least isn't always.

  • I've reworded my question to be more clear. We do not wish to support 4.6.2 code in our scripts, thus what I want is the script compiled against 4.5. If someone tried to use the new method, I'd expect a compile error instead. I'm not following your response in terms of whether it's a proposed solution or if you're saying there's no way to work around the issue. – Sean Beanland Oct 28 '16 at 20:39
  • So where are your scripts compiled? On your system, or the end user's? The name "script" implies the latter. You can either find a way to compile on your own system where you have the reference assemblies, or make sure the user has the reference assemblies. Either way, nothing impossible about it, just make sure to use them. –  Oct 28 '16 at 21:48