C# Compiler Warning 1685 - c#

So, (seemingly) out of the blue, my project starts getting compiler warning 1685:
The predefined type
'System.Runtime.CompilerServices.ExtensionAttribute'
is defined in multiple assemblies in
the global alias; using definition
from 'c:\Program Files\Reference
Assemblies\Microsoft\Framework\v3.5\System.Core.dll'
Perplexed, I researched the MSDN article to figure out its cause. Here's the information I found:
Visual C# Reference: Errors and
Warnings Compiler Warning (level 1)
CS1685
Error Message The predefined type
'System.type name' is defined in
multiple assemblies in the global
alias; using definition from 'File
Name'
This error occurs when a predefined
system type such as System.int32 is
found in two assemblies. One way this
can happen is if you are referencing
mscorlib from two different places,
such as trying to run the.Net
Framework versions 1.0 and 1.1
side-by-side.
The compiler will use the definition
from only one of the assemblies. The
compiler searches only global aliases,
does not search libraries defined
/reference. If you have specified
/nostdlib, the compiler will search
for Object, and in the future start
all searches for predefined types in
the file where it found Object.
Now I'm really scratching my head.
I'm not running two different
versions of the .NET Framework
(unless you count 2.0 and 3.5).
I'm not referencing any bizarre
assemblies that might make me
suspicious.
I don't recall making any changes to my application that would spur this change.
I've verified that all components target .NET Framework version v2.0.50727.
I'm open to suggestions, or ideas on how to correct this. I treat warnings as errors, and it's driving me crazy.
What really bugs me about it is that I don't know why it's occurring. Things that happen should have a discernable cause, and I should know why they happened. If I can't explain it, I can't accurately remedy it. Guesswork is never satisfactory.
The application is straightforward, consisting of a class library, and a windows forms application.
A C# class library DLL providing basic functionality encapsulating database access. This DLL references the following components:
System
System.Core
System.Core.Data
System.Data
System.Data.DataSetExtensions
System.Data.OracleClient
System.Drawing
System.Windows.Forms
System.Xml
System.Xml.Linq
A C# Windows Forms application providing the UI. This application references the following components:
CleanCode
CleanCodeControls (both of these provide syntax editor support, and are locally built against .NET 3.5).
LinqBridge
Roswell.Framework (the class library above)
System
System.Core
System.Data
System.Data.DataSetExtensions
System.Data.OracleClient
System.Deployment
System.Design
System.Drawing
System.Windows.Forms
System.Xml
System.Xml.Linq
Let me know if you need further information and I'll gladly provide it.

Another easy way to verify:
In your code, temporarily use the class somewhere.
Example:
System.Runtime.CompilerServices.ExtensionAttribute x = null;
When building, this will generate error:
The type 'System.Runtime.CompilerServices.ExtensionAttribute' exists
in both 'c:\Program Files\Reference
Assemblies\Microsoft\Framework\v3.5\System.Core.dll' and .....
And show you immediately the 2 sources causing the conflict.

LINQBridge makes me immediately suspicious. The entire intent of this is to provide extension attribute/methods etc for 2.0 users. If you have 3.5 (System.Core.dll), don't use LINQBridge. If you do need LINQBridge in 3.5 for some obscure reason (and I can't think of one), then you might have to use an extern alias. But I really doubt you need it!

Marc is almost certainly correct. Here's a way to verify
Open Reflector.exe
Add all of Non-System assemblies
F3 and search for ExtensionAttribute
If it pops up anywhere besides System.Core then you know where it's coming from.

Another solution for this issue is to use a global alias for the whole assembly:
Reference -> Properties -> Aliases -> Replace 'global' with something else

FYI: I had the same problem and was able to resolve it by using Resharper's "Optimize References" command, and then removing all unused references. Not completely sure why that worked, but it did.

My teams resolution for this CS1685 warning was removing the binding redirect for System.Text.Json.
<dependentAssembly>
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>

Another solution for this issue => Right click project -> Properties -> Build -> Treat warnings as errors -> None

Related

Create placeholder .NET assembly [duplicate]

Since version 3.0, .NET installs a bunch of different 'reference assemblies' under C:\Program Files\Reference Assemblies\Microsoft...., to support different profiles (say .NET 3.5 client profile, Silverlight profile). Each of these is a proper .NET assembly that contains only metadata - no IL code - and each assembly is marked with the ReferenceAssemblyAttribute. The metadata is restricted to those types and member available under the applicable profile - that's how intellisense shows a restricted set of types and members. The reference assemblies are not used at runtime.
I learnt a bit about it from this blog post.
I'd like to create and use such a reference assembly for my library.
How do I create a metadata-only assembly - is there some compiler flag or ildasm post-processor?
Are there attributes that control which types are exported to different 'profiles'?
How does the reference assembly resolution at runtime - if I had the reference assembly present in my application directory instead of the 'real' assembly, and not in the GAC at all, would probing continue and my AssemblyResolve event fire so that I can supply the actual assembly at runtime?
Any ideas or pointers to where I could learn more about this would be greatly appreciated.
Update: Looking around a bit, I see the .NET 3.0 'reference assemblies' do seem to have some code, and the Reference Assembly attribute was only added in .NET 4.0. So the behaviour might have changed a bit with the new runtime.
Why? For my Excel-DNA ( http://exceldna.codeplex.com ) add-in library, I create single-file .xll add-in by packing the referenced assemblies into the .xll file as resources. The packed assemblies include the user's add-in code, as well as the Excel-DNA managed library (which might be referenced by the user's assembly).
It sounds rather complicated, but works wonderfully well most of the time - the add-in is a single small file, so no installation of distribution issues. I run into (not unexpected) problems because of different versions - if there is an old version of the Excel-DNA managed library as a file, the runtime will load that instead of the packed one (I never get a chance to interfere with the loading).
I hope to make a reference assembly for my Excel-DNA managed part that users can point to when compiling their add-ins. But if they mistakenly have a version of this assembly at runtime, the runtime should fail to load it, and give me a chance to load the real assembly from resources.
To create a reference assembly, you would add this line to your AssemblyInfo.cs file:
[assembly: ReferenceAssembly]
To load others, you can reference them as usual from your VisualStudio project references, or dynamically at runtime using:
Assembly.ReflectionOnlyLoad()
or
Assembly.ReflectionOnlyLoadFrom()
If you have added a reference to a metadata/reference assembly using VisualStudio, then intellisense and building your project will work just fine, however if you try to execute your application against one, you will get an error:
System.BadImageFormatException: Cannot load a reference assembly for execution.
So the expectation is that at runtime you would substitute in a real assembly that has the same metadata signature.
If you have loaded an assembly dynamically with Assembly.ReflectionOnlyLoad() then you can only do all the reflection operations against it (read the types, methods, properties, attributes, etc, but can not dynamically invoke any of them).
I am curious as to what your use case is for creating a metadata-only assembly. I've never had to do that before, and would love to know if you have found some interesting use for them...
If you are still interested in this possibility, I've made a fork of the il-repack project based on Mono.Cecil which accepts a "/meta" command line argument to generate a metadata only assembly for the public and protected types.
https://github.com/KarimLUCCIN/il-repack/tree/xna
(I tried it on the full XNA Framework and its working afaik ...)
Yes, this is new for .NET 4.0. I'm fairly sure this was done to avoid the nasty versioning problems in the .NET 2.0 service packs. Best example is the WaitHandle.WaitOne(int) overload, added and documented in SP2. A popular overload because it avoids having to guess at the proper value for *exitContext" in the WaitOne(int, bool) overload. Problem is, the program bombs when it is run on a version of 2.0 that's older than SP2. Not a happy diagnostic either. Isolating the reference assemblies ensures that this can't happen again.
I think those reference assemblies were created by starting from a copy of the compiled assemblies (like it was done in previous versions) and running them through a tool that strips the IL from the assembly. That tool is however not available to us, nothing in the bin/netfx 4.0 tools Windows 7.1 SDK subdirectory that could do this. Not exactly a tool that gets used often so it is probably not production quality :)
You might have luck with the Cecil Library (from Mono); I think the implementation allows ILMerge functionality, it might just as well write metadata only assemblies.
I have scanned the code base (documentation is sparse), but haven't found any obvious clues yet...
YYMV

How come I don't need to reference "System.dll" to use the "System" namespace?

I am working on an assignment that specified "Do not use any external libraries". So I created a c# application, and the first thing I did was remove all the dll's references by default... including "System.dll".
However, I can still add this to my code:
using System;
using System.IO;
I was just curious as to how come I do not need to have System.dll as a reference in my project to do this. Thanks!
mscorlib.dll includes items in both those namespaces.
You need to right-click your project > Properties > Build > Advanced... and check "Do not reference mscorlib.dll" to remove this reference.
Different assemblies can contribute to the same namespace.
Even if you don't reference System.dll, you are still referencing (implicitly) mscorlib.dll which contributes many types to the System namespace.
These references are probably defined in your Web.config or the Machine.config file so they're included by default.
These are the default libraries.I think your question is that "Dont use third party dlls"
Another thing to consider is, if you're compiling directly through the command line, a default set of switches, including default library references, is parsed by the compiler through the default response file (csc.rsp), located in the same directory as the compiler. The fact that you are able to import namespaces from the Base Class Library without explicitly referencing them at compile time is due to the fact that their containing assemblies are included in your program by default. To change this behavior at the command line, you can use the /nostdlib switch to force it not to include mscorlib.dll, or you can use /noconfig to have it ignore the entire default response file altogether. Also, I'm not too sure what you mean by system.dll, because the namespaces you mentioned are contained within mscorlib.dll. Also, I think by "external library", your instructor must have meant any 3rd party assemblies that would assist you in solving the problem. Anything that comes included with the .NET SDK would be more of a framework library. Unless your teacher is really harsh and wants you to reinvent the wheel :P

HUGE problems using CodeDom compiler, can't use namespaces in the dynamic code

I'm trying to create dynamically generated code based on user input (just like a mini-compiler). But my problem is that i need to use the PresentationFramework.dll assembly inside the dynamic code, and i don't know how to reference it.
I have already tried Assembly.Load() and Assembly.Loadfrom(). But all i get is an error saying:
"Assembly not found"
I am used to doing this with the IDE (right click references and then add), but now i need to find some way to do this through code.
I need the assembly to use System.Windows.Shell to create custom jumplists.
This isn't just happening for this specific assembly, but for several others too. But this is the most important one, so if someone could help me with this i would be thankful.
So the baseline is: I need to use the namespace System.Windows.Shell. I need to reference this namespace fully through code (no IDE). How can this be done? And is it even possible?
I'm using Visual Studio 2010 Ultimate (C#).
Thanks in advance!
It depends on the version of PresentationFramework you want when you need to add it as a reference. Basically, you will find it in :
\Program File\Reference Assemblies\Microsoft\Framework
(for 64-bit compilation, or 32-bit on a 32-bit OS)
or
\Program File (x86)\Reference Assemblies\Microsoft\Framework
(for 32-bit compilation or 32-bit on a 64-bit OS)
These are only the root folders. From here, you can go for example in "v3.0" or ".NETFramework\v4.0" for example.
So you just need to add a reference to a full "[path]\PresentationFramework.dll" instead of just "PresentationFramework.dll", for example:
"C:\Program File\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\PresentationFramework.dll".
Here is the answer straight from MSDN:
If your project references any
assemblies, you must specify the
assembly names as items in a
StringCollection as the
ReferencedAssemblies property of the
CompilerParameters you use when
invoking compilation.

Loading an assembly from any version

I'm referencing a signed assembly. In runtime it is ok for me to work with any version of that assembly, not just the one I compiled to.
How to achieve this?
No, that's not going to work. The CLR will verify the assembly version number, expecting to get the one that your main program was compiled against. You would have to use the <bindingRedirect> element in the app.config file to convince it that a different version is okay.
That's a slippery slope. Consider only changing the [AssemblyVersion] attribute if the public interface of the assembly changed and requires clients to be recompiled. Now the exception you'll get is one that identifies a real problem. This is another kind of slippery slope, but one you'll have much more control over.
For comparison, this is the way all the base assemblies in the .NET framework work. There have been many revisions of them between .NET 2.0 RTM and 3.5 SP1, including many invisible hotfixes. But the [AssemblyVersion] is still 2.0.0.0, Microsoft only modifies the [AssemblyFileVersion].
In the IDE, make sure "Specific Version" is set to false against the reference, or add <SpecificVersion>False</SpecificVersion> to the reference in the csproj.

strange warning about ExtensionAttribute

I'm getting a strange warning:
The predefined type 'System.Runtime.CompilerServices.ExtensionAttribute' is defined in multiple assemblies in the global alias; using definition from 'c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll'
There is no line number given, so it's hard to figure out what it's on about.
The compiler error code is CS1685
Are you using someone's dll (or your own) which had implemented this attribute (with exactly the same name) itself as a means of using some c# 3.0 features on pre .Net 3.5 runtimes? (A common trick)
This is the probable cause. Since it is using the correct one (the MS one in the GAC) this is not a problem though you should hunt down the other and remove it.
Expanding on ShuggyCoUk's (correct) answer
Truthfully it doesn't matter which version of the attribute is used (GAC, 3rd part, etc ...). All that matters is the C#/VB compiler can find some attribute with the correct name. The attribute serves no functional purpose in code. It exists purely to tell the Compiler "hey, this is an extension method".
You can safely ignore this warning.
I agree with ShuggyCoUk that the best course of action is to try to remove the offending dll. That may not be possible, though.
Another way to resolve the ambiguity that the compiler is complaining about is to change the Alias of the referenced dll. In your project, in the References folder, if you click on a referenced dll you will see the Aliases property. By default, this is "global", which allows you to do things like "global::SomeNamespace.SomeType". You might simply be able to change the alias to something else.
This fixed a problem I had where I needed to reference Microsoft.Scripting.Core.dll, but it contained some types that conflicted with mscorlib.dll. I changed the Aliases property to be "ThirdParty" instead of "global", and that fixed the warning.
I have the same problem.
In my case the problem was the assembly Mono.Cecil.
Migrating from local references to nuget, when i add NHibernate references the package automatically adds this reference.
This reference was removed, and compiled my project again.
Remove it and be happy!!
This image was taken from ILSpy ( http://i.stack.imgur.com/Qyd5o.png )
The compiler does not know which System.Runtime.CompilerServices.ExtensionAttribute
So it is using the defination from c:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll'
A .dll you are using might have the same extenstion.
I triggered this error by installing IIS with .NET 3.5 instead of 4.5 by accident.
Fix was to add 4.5 back in in "Add Features ..." in control panel.

Categories