Äquivalent von C ++ 's reininterpret_cast in C #

8

Ich frage mich, was C ++% reinterpret_cast in C # bedeutet !?

Hier ist mein Beispiel:

%Vor%

Ich habe keine Einwände, warum f null sein wird, da es so sein sollte. Aber wenn es C ++ wäre, hätte ich Foo f = reinterpret_cast<Foo>(b); schreiben und bekommen können, was ich wollte. Was kann ich tun, um dasselbe in C # zu erreichen?

PS. Ich nehme an, dass Base und Foo Daten konsistent sind.

[UPDATE]

Hier ist ein einfaches Szenario, in dem ein reinterpret_cast hilfreich sein könnte:

Ziehen Sie in Betracht, eine XXX-RPC-Bibliothek zu schreiben, in der Sie weder die eingehenden Parameter noch die Signatur der zu rufenden Dienste kontrollieren können. Ihre Bibliothek sollte den angeforderten Dienst mit den angegebenen Parametern aufrufen. Wenn C # reinterpret_cast unterstützt, könnte ich einfach reinterpret_cast die gegebenen Parameter in die erwarteten setzen und den Service aufrufen.

    
Mehran 21.10.2013, 14:51
quelle

7 Antworten

3

Diskussion

Wie einige der Antworten zeigen, setzt .Net die Typensicherheit streng im Bereich der Frage durch. A reinterpret_cast wäre eine inhärent unsichere Operation, daher wären die möglichen Wege, um eins zu implementieren, entweder durch Reflexion oder Serialisierung , während die beiden verwandt sind.

Wie Sie in einem Update erwähnt haben, könnte eine mögliche Verwendung ein RPC-Framework sein. RPC-Bibliotheken verwenden normalerweise Serialisierung / Reflexion, und es gibt ein paar verwendbare:

Vielleicht möchten Sie vielleicht gar nicht selbst einen selbst schreiben.

Wenn Ihre Klasse Base öffentliche Eigenschaften verwenden würde, könnten Sie AutoMapper verwenden:

%Vor%

...

%Vor%

Wo Foo überhaupt nicht von Base abgeleitet werden muss. Es muss nur die Eigenschaft haben, auf die Sie sich beziehen möchten. Aber auch hier brauchen Sie vielleicht gar keine zwei Typen - ein Umdenken der Architektur könnte die Lösung sein.

In der Regel ist es nicht erforderlich, reinterpret_cast über eine saubere Architektur zu verwenden, die in die im .Net-Framework verwendeten Muster passt. Wenn Sie immer noch darauf bestehen, so etwas zu haben, finden Sie hier eine Lösung mit der kompakten Serialisierungsbibliothek protobuf-net .

Serialisierungslösung

Ihre Klassen:

%Vor%

und ein ausführbares Serialisierungs-Deserialisierungs-Beispiel:

%Vor%

Ausgabe

%Vor%

Wenn Sie in Ihrem Vertrag keine abgeleiteten Typen deklarieren möchten, lesen Sie dieses Beispiel ...

Wie Sie sehen, ist die Serialisierung sehr kompakt.

Wenn Sie mehr Felder verwenden möchten, können Sie die implizite Serialisierung von Feldern versuchen:

%Vor%

Ein generisches reinterpret_cast könnte definitiv entweder über diese Serialisierungslösung oder direkt über Reflektion implementiert werden, aber ich würde die Zeit im Moment nicht investieren.

    
Dmitry Ledentsov 22.10.2013, 09:06
quelle
3

Sie können möglicherweise ein ähnliches Verhalten mit unsafe blocks und void* in C # erreichen:

%Vor%

Verwendung:

%Vor%

Nicht getestet.

Die struct-Bedingungen machen den Punkt Ihrer Frage wahrscheinlich überflüssig, aber sie sind notwendig, da Klassen vom GC verwaltet werden, so dass Sie keine Zeiger darauf haben dürfen.

    
James Ko 07.08.2015 21:46
quelle
3

Das funktioniert. Und ja, es ist so böse und so großartig, wie du dir nur vorstellen kannst.

%Vor%

Eine Sache, die Sie beachten sollten ist, dass wenn Sie T[] auf und U[] umsetzen:

  • Wenn T größer als U ist, verhindert die Begrenzungsprüfung, dass Sie auf die U Elemente nach der ursprünglichen Länge von T[] zugreifen können.
  • Wenn T kleiner als U ist, können Sie mit der Überprüfung der Grenzen nach dem letzten Element (effektiv ist es eine Pufferüberlauf-Schwachstelle)
  • lesen
Nick Strupat 06.02.2017 23:09
quelle
2

C # hat nicht das Loch im Typensystem, das Ihnen erlauben würde, dies zu tun. Es weiß, um welche Art von Dingen es sich handelt, und erlaubt dir nicht, auf einen anderen Typ zu wirken. Die Gründe dafür sind ziemlich offensichtlich. Was passiert, wenn Sie Foo ein Feld hinzufügen?

Wenn du einen Typ von Foo willst, musst du einen Typ von Foo erstellen. Eine bessere Route könnte ein Konstruktor vom Typ Foo sein, der eine Basis als Parameter verwendet.

    
Joel 21.10.2013 14:58
quelle
1

Dies ist meine 'Implementierung'

%Vor%

Stellen Sie sicher, dass Sie wissen, was Sie tun, wenn Sie es aufrufen, insbesondere bei Referenztypen.

    
Jay 04.05.2016 00:58
quelle
0

Da b nur eine Instanz von Base ist, können Sie es niemals in eine Instanz von Foo konvertieren, die nicht null ist. Vielleicht könnte eine Schnittstelle Ihren Anforderungen besser entsprechen?

    
Bill Gregg 21.10.2013 14:53
quelle
0

Wenn Foo und Bar Strukturen wären, könntest du

machen %Vor%

aber ich bin mir nicht sicher, ob das an Objekten funktionieren würde.

    
mg30rg 09.11.2017 09:48
quelle

Tags und Links