8 Stimmen

Nicht alphanumerische Zeichen in COM/.NET-Schnittstellennamen

Ich denke an die Verwendung der Zeichen #@! in einigen COM-Schnittstellen, die unser System erzeugt. Die COM-Typenbibliothek wird auch nach .NET exportiert. Werden mir diese Zeichen später Probleme bereiten?

Ich habe es heute den größten Teil des Tages getestet, und es scheint alles in Ordnung zu sein. Unser System funktioniert weiterhin so wie immer.

Der Grund, warum ich vorsichtig bin, ist, dass diese Zeichen in MIDL, die C-Syntax für Typnamen verwendet, illegal sind. Aber wir verwenden nicht MIDL - wir bauen unsere Typbibliotheken mit ICreateTypeInfo und ICreateTypeLib. Es sieht so aus, als ob das nur eine MIDL-Beschränkung ist, und COM und .NET sind mit den nicht-alphanumerischen Zeichen zufrieden. Aber vielleicht gibt es etwas, das ich nicht weiß...

2voto

Ciaran Keating Punkte 2728

Das habe ich herausgefunden.

Ich denke, es gibt keine Frage, dass die Namen auf der binären Ebene in COM legal sind, da der Name einer COM-Schnittstelle seine IID ist und der Textname nur Dokumentation ist.

Auf der .NET-Seite ist die relevante Spezifikation die Spezifikation der Common Language Infrastructure (ECMA-335), http://www.ecma-international.org/publications/standards/Ecma-335.htm .) Ich frage mich, ob .NET oder Mono ihre eigenen Einschränkungen hinzufügen - dies würde die Interoperabilität verringern, aber das ist die reale Welt.

Abschnitt 8.5.1 behandelt gültige Typnamen im Common Type System und besagt lediglich, dass Namen anhand von Codepunkten verglichen werden. Seltsam, dass hier nichts über die Zusammensetzung eines Namens steht, sondern nur darüber, wie Namen verglichen werden. Dieser Abschnitt wird von MSDN umschrieben unter http://msdn.microsoft.com/en-us/library/exy17tbw%28v=VS.85%29.aspx die besagt, dass die einzigen beiden Einschränkungen darin bestehen, dass (1) Typnamen "als Zeichenketten aus Unicode-Zeichen (16 Bit) kodiert" sind und (2) sie kein eingebettetes 0x0000 enthalten dürfen.

Ich habe den Teil über 16-Bit-Unicode zitiert, anstatt ihn zu umschreiben, weil er ungenaue Formulierungen enthält. Vermutlich meinte der Autor dieser Seite UTF-16. Auf jeden Fall spezifiziert ECMA-335 den Byte-für-Byte-Vergleich und erwähnt weder Unicode (in Bezug auf Typnamen) noch verbietet es eingebettete Nullen. Vielleicht ist .NET hier vom CTS abgewichen, obwohl ich das bezweifle. Wahrscheinlicher ist, dass der Autor dieser MSDN-Seite an Programmiersprachen gedacht hat, als er sie schrieb.

Die Common Language Specification (ebenfalls in ECMA-335 definiert) legt die Regeln für Bezeichner im Quellcode fest. Bezeichner sind für meine Frage nicht direkt relevant, da meine internen Typnamen nie im Quellcode erscheinen, aber ich habe mir das trotzdem angeschaut. Das CLS ist eine Teilmenge des CTS, und als solche sind seine Einschränkungen nicht unbedingt Teil des umfassenderen CTS. CLS-Regel 4 besagt, dass Bezeichner den Regeln von Anhang 7 des Technical Report 15 des Unicode-Standards 3.0 folgen müssen - siehe http://www.unicode.org/reports/tr15/tr15-18.html . Auch dieses Dokument ist insofern etwas vage, als es sich auf "andere Buchstaben" und "Verbindungszeichen" bezieht, diese aber nicht definiert. Das hat geholfen: http://notes.jschutz.net/topics/unicode/ .

Abschnitt 8.5.1 der ECMA-Spezifikation enthält einen nicht-normativen Hinweis, dass ein CLS-Konsument (z. B. C# oder der Visual Studio-Typbrowser) "keine Typen verwenden muss, die gegen CLS-Regel 4 verstoßen". Die von mir vorgeschlagenen Schnittstellennamen verletzen diese Regel 4. Dieser Hinweis scheint zu implizieren, dass ein gültiger Typ einen Namen haben kann, der gegen Regel 4 verstößt, und dass ein CLS-Verbraucher entweder den Schurken-Namen akzeptieren oder ihn sicher ignorieren sollte. (Der Typbrowser von Visual Studio zeigt ihn ohne Beanstandung an.)

Daher sind die von mir vorgeschlagenen Typennamen im Quellcode generell unzulässig. Aber beachten Sie, dass Abschnitt 10.1 (über Bezeichner im CLS) sagt: "Da die Regeln nur für Elemente gelten, die in andere Sprachen exportiert werden, können private Mitglieder oder Typen, die nicht von einer Assembly exportiert werden, beliebige Namen verwenden."

Ich bin zu dem Schluss gekommen, dass es sicher ist, die Zeichen #@! in meinen Typnamen zu verwenden, solange sie in der Binärdomäne bleiben und niemals im Quellcode oder außerhalb der Assembly erscheinen müssen. Und in der Tat werden sie nie außerhalb des COM-Servers verwendet.

Ein Wort zur Zukunftssicherheit... Das CTS sagt so gut wie nichts über die Zusammensetzung von Typnamen aus, obwohl es einen Abschnitt mit dem Titel "Gültige Namen" (Abschnitt 8.5.1) gibt. Das könnte sich in Zukunft ändern, aber diese breite und liberale Spezifikation hat uns alle dazu eingeladen, zu tun, was wir wollen. Hätten die CTS-Entwickler Raum für Änderungen lassen wollen, dann hätten sie sicherlich einige Vorkehrungen dafür getroffen, oder zumindest weniger großzügig sein müssen.

1voto

jimhark Punkte 4753

Es ist interessant, dass Sie anscheinend ein Schlupfloch in der Benennung von COM-Typen gefunden haben. Microsoft schränkt die Verwendung von Zeichen "#@!" als Bezeichner in MIDL ein, aber sie duplizieren diese Einschränkung nicht in den Schnittstellen ICreateTypeInfo und ICreateTypeLib.

Die Verwendung dieser Zeichen funktioniert heute, was ist also das Risiko?

  1. Nun, Microsoft könnte dies als eine Fehler sehen und ICreateTypeInfo 'beheben', ICreateTypeLib, .Net COM Interop, und/oder .Net Typbenennung Einschränkungen in der nächsten Version.

  2. Sie erstellen und verwenden eine Schnittstelle, die keine gültige MIDL-Definition hat.

  3. Sie verwenden Namen, die wahrscheinlich ändern müssen, wenn (wenn) Sie von COM zu .Net wechseln. Selbst wenn Sie nur einen Adaptertyp in .Net erstellen wollen, werden Sie nicht der "ungültigen" Namen wiederverwenden Namen verwenden.

  4. Ist dies kompatibel mit Mono und anderen nicht-Microsoft .Net-kompatiblen Technologien?

  5. Es gibt viele bekannte gültige Namen, die verwendet werden können (verwenden Sie etwas wie ' _at_ ' anstelle von ' @ ', usw.), um mögliche zukünftige Probleme zu vermeiden.

Wenn Ihnen das alles nichts ausmacht, werden Sie wahrscheinlich keine Probleme haben. Aber ich vermute, dass allein die Tatsache, dass Sie diese Frage gestellt haben, sich für Sie irgendwie nicht richtig anfühlt.

Viel Glück!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X