Ich fand ein seltsames Verhalten in VS2015 Hier sind die Details:Warum werden optionale Parameter in Visual Studio 2015 falsch übergeben?
Ich habe ein .Net 4.6-Projekt Verweis auf eine 3.5-Assembly. Diese Assembly definiert in einer ihrer Schnittstellen die folgende Methode, die ich mit Resharper Decompiler überprüfen konnte.
void WriteString([MarshalAs(UnmanagedType.BStr), In] string data, [In] bool flushAndEND = true);
Beachten Sie die letzte optionale Argument flushAndEND
, die einen Standardwert von true
hat. Das Problem ist jetzt, wenn ich diese Methode in meinem Projekt benutze, den Mauszeiger über dem Methodennamen den üblichen VS-ToolTip zeigt, der die Methodensignatur angibt, außer dass er für mich einen falschen Standardwert des optionalen Arguments flushAndEND
anzeigt. Hier ist ein Screenshot
Um die Dinge noch schlimmer zu machen, ich habe bemerkt, dass während der Laufzeit, wenn das Verfahren WriteString
nur mit dem ersten Parameter aufrufen, flushAndEND
-false
gesetzt wird und nicht den Standardwert in der DLL definiert Ich referenziere. Die Auswirkung auf unser Projekt war groß, weil es ein großes Merkmal unserer App nutzlos machte und einen großen Teil unserer Regressionstests blockierte.
Ich konnte dieses Problem überwinden, indem ich den Wert des optionalen Arguments beim Aufruf der Methode auf true setzte, aber ich fürchte, es gibt andere Aufrufe an einem anderen Ort im Projekt, die unter dem gleichen Problem leiden. Ich werde dafür eine bessere Lösung brauchen oder zumindest verstehen, was die Ursache für dieses Verhalten ist.
Wir haben gerade unsere Umgebung vor einigen Wochen aufgerüstet. Bevor wir VS2013 benutzt haben und alles hat gut funktioniert.
Ich bin mir der confirmed .Net 4.6 bug bewusst, die verursacht, dass einige Argumente falsche Werte übergeben werden, und ich kann es auf mein Problem hier beziehen, aber wie es in dem Artikel gesagt wird, tritt der Fehler nur beim Kompilieren für x64-Architektur auf. Mein Projekt ist eine WPF-Anwendung und wir kompilieren es als x32.
Warum wird WriteString
mit falschem Standardargument aufgerufen?
Ich werde später versuchen, das Problem in einem kleinen Projekt zu isolieren und sehen, ob ich das Problem reproduzieren kann.
EDIT: Ich habe es geschafft, das Problem zu isolieren, und einige interessante Sachen gefunden!
habe ich eine einfache .NET 4.6-Konsole-Anwendung, hat einen Verweis auf meine Dll und schrieb den folgenden einfachen Code, der sich auf eine Vorrichtung zum Senden eines Befehls aus und liest die Antwort:
private static void Main(string[] args)
{
//Init managers
ResourceManager ioMgr = new ResourceManagerClass();
FormattedIO488 instrument = new FormattedIO488Class();
//Connect to the USB device
instrument.IO = (IMessage)ioMgr.Open("USB0::0x0957::0x0909::MY46312358::0::INSTR");
string cmd = "*IDN?";
//This is the problematic method from my dll
instrument.WriteString(cmd);
//Read the response
string responseString = instrument.ReadString();
Console.WriteLine(responseString);
Console.ReadKey();
}
Was ich tat, Als nächstes wird dieses Projekt sowohl von VS 2013 als auch von VS 2015 geöffnet. In beiden Versionen von VS habe ich das Projekt neu erstellt und ausgeführt. Hier sind die Ergebnisse:
VS2013: WriteString
wurde mit dem richtigen Standardwert von flushAndEND
genannt (die true
Bedeutung der Puffer spülen und den Befehl beenden).
VS2015: WriteString
wurde mit dem WRONG-Standardwert flushAndEND
aufgerufen, der eine Zeitüberschreitungsausnahme ergab.
Weitere Kontrollen zwischen den beiden Versionen von Visual Studio zeigt, dass der Viewer-Objekt-Browser in VS2013 die Methodensignatur wie zeigt:
void WriteString(string data, [bool flushAndEND = True])
, während das Objekt-Browser in VS2015 zeigt die Methodensignatur als:
void WriteString(string data, [bool flushAndEND = False])
Die einzige Erklärung für dieses Verhalten ist, dass ein Problem mit VS2015 Compiler nicht richtige Standardwerte aus der Assembly lesen.
Ähm, also IntelliSense zeige es als * false * und der Compiler interpretiert es als * false *, es ist nur der Resharper Decompiler, der * true * anzeigt. Wie ist das kein Resharper-Fehler? Sieht aus wie eine COM-Komponente, aktualisieren Sie die Interop-Bibliothek, indem Sie die .NET 4-Version von Tlbimp.exe –
Ich glaube, dass der richtige Standardwert sollte wahr sein, weil dies bedeutet, in den Puffer schreiben und sofort flush. Und ja, es ist eine COM-Komponente. Ich werde Ihren Vorschlag so schnell wie möglich versuchen. – disklosr
@HansPassant Können Sie zeigen, wie Sie das Tool Tlbimp.exe verwenden? Vielen Dank! – disklosr