Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Typecasting in C# (https://www.delphipraxis.net/127774-typecasting-c.html)

Neutral General 18. Jan 2009 22:41


Typecasting in C#
 
Hi,

In Delphi geht ja folgendes:

Delphi-Quellcode:
var x: TObject;
    y: TButton;
begin
  x := y;
end;
Das geht in C# nicht. Ich habe meine SocketEx-Klasse von Socket abgeleitet und mein Problem ist gerade, dass Socket.Accept() ein Socket zurück gibt und er mir das weder implizit noch explizit konvertieren will.

Code:
SocketEx tmp;

tmp = (SocketEx)server.Accept();
Das compiliert zwar, wirft aber eine Exception. Weiß jemand wies geht?

Elvis 18. Jan 2009 22:53

Re: Typecasting in C#
 
Zitat:

Zitat von Neutral General
Hi,
In Delphi geht ja folgendes:
Delphi-Quellcode:
var x: TObject;
    y: TButton;
begin
  x := y;
end;
Das geht in C# nicht.

Natürlich ginge das in C#! :shock:
Zitat:

Ich habe meine SocketEx-Klasse von Socket abgeleitet und mein Problem ist gerade, dass Socket.Accept() ein Socket zurück gibt und er mir das weder implizit noch explizit konvertieren will.
Code:
SocketEx tmp;
tmp = (SocketEx)server.Accept();
Das compiliert zwar, wirft aber eine Exception. Weiß jemand wies geht?
Gibt "Accept" denn auch wirklich eine Instanz zurück, die SocketEx ode reiner seiner Nachfahren ist?
In Delphi kannst du alles auf alles casten, weil Delphi zur Laufzeit nicht Typsafe ist.
.Net IST typesafe. Du kannst nicht eine Referenz von Socket als SocketEx nutzen, wenn die Referenz nicht auf eine Instanz von SocketEx oder einen Nachfahren zeigt.

das hier würde gehen:
Code:
Socket ref1 = new SocketEx();
SocketEx ref2 = (SocketEx)ref1;

Neutral General 18. Jan 2009 23:17

Re: Typecasting in C#
 
Hi,

Also so sieht meine (noch sehr bescheidene^^) SocketEx Klasse aus:

Code:
public class SocketEx:Socket
{
   public bool isbusy;   
      
   SocketEx(AddressFamily addr, SocketType socktype,ProtocolType protoc):base(addr,socktype,protoc)
   {
         
   }
}
Die Methode Accept() von Socket gibt ein Socket zurück. Quasi:
Code:
public Socket Accept()
{
  // ka
}
und folgendes geht nicht:

Code:
public static SocketEx server = new SocketEx(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

// ...

SocketEx tmp;
tmp = server.Accept();
Meldung:

Zitat:

Der Typ System.Net.Sockets.Socket kann nicht implizit in TestServer.SocketEx konvertiert werden. Es ist eine explizite Konvertierung vorhanden. (Fehlt eine Umwandlung?) (CS0266) - I:\CSharp\TestServer\Program.cs:114,11

xaromz 18. Jan 2009 23:34

Re: Typecasting in C#
 
Hallo,

sowas kann ja nicht gehen. Du hast eine Variable vom Typ einer abgeleiteten Klasse, und willst ihr ein Objekt der Basisklasse zuweisen. Andersrum wird ein Schuh draus. Sowas klappt auch in Delphi nicht.

Gruß
xaromz

Neutral General 18. Jan 2009 23:49

Re: Typecasting in C#
 
Ehm Recht hast du.

Aber wie löse ich denn jetzt mein Problem konkret? Das muss doch gehn?! Ich steh grad aufm Schlauch :?

Phoenix 19. Jan 2009 08:05

Re: Typecasting in C#
 
Zitat:

Zitat von Neutral General
Die Methode Accept() von Socket gibt ein Socket zurück. Quasi:
Code:
public Socket Accept()
{
  // ka
}
und folgendes geht nicht:

Code:
public static SocketEx server = new SocketEx(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
// ...
SocketEx tmp;
tmp = server.Accept();

Na, wenn Du einen Socket zurückgibst, musst Du auch einen Socket als Variable deklarieren:
Code:
SocketEx server = new SocketEx(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Socket tmp = server.Accept();

Neutral General 19. Jan 2009 08:16

Re: Typecasting in C#
 
Zitat:

Zitat von Phoenix
Na, wenn Du einen Socket zurückgibst, musst Du auch einen Socket als Variable deklarieren:
Code:
SocketEx server = new SocketEx(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Socket tmp = server.Accept();

Ah joo.. Schon klar, dass das so geht. Und wie bekomm ich.... moment!

Das Problem ist einfach, dass das Socket was ich von Accept() zurückbekomme eben nur ein Socket ist und kein SocketEx -.- Also kann ich da noch so viel rumcasten. Wenns kein SocketEx ist, ists kein SocketEx... :|

Toll -.- Jetzt bin ich mit meinem (C#-)Latein am Ende :(

Jürgen Thomas 19. Jan 2009 09:12

Re: Typecasting in C#
 
Denkt doch nicht so kompliziert! So einfach geht es:
Code:
SocketEx ext = server.Accept() as SocketEx;
if (ext != null) // usw.
Begründung: Accept liefert eine Socket-Instanz. Wenn es sich dabei aufgrund der äußeren Umstände wirklich um eine SocketEx-Instanz handelt, kann es mit as einfach konvertiert werden. Dies hat außerdem den Vorteil, dass die as-Konvertierung im Fehlerfall null zurückliefert, ohne dass es zu einer Exception führt. Dies kann (besser: sollte in der Regel) vor der Fortsetzung geprüft werden.

Das besagte auch die obige Fehlermeldung:
Zitat:

Es ist eine explizite Konvertierung vorhanden. (Fehlt eine Umwandlung?)
nämlich "as" benutzen als explizite Konvertierung.

Gruß Jürgen

Khabarakh 19. Jan 2009 10:29

Re: Typecasting in C#
 
Beschreibe doch einmal näher, was du mit deiner SocketEx-Klasse vorhast. Wenn es ein Wrapper werden soll, ist Vererbung der falsche Weg.

Neutral General 19. Jan 2009 11:50

Re: Typecasting in C#
 
Zitat:

Zitat von Jürgen Thomas
Denkt doch nicht so kompliziert! So einfach geht es:
Code:
SocketEx ext = server.Accept() as SocketEx;
if (ext != null) // usw.
Begründung: Accept liefert eine Socket-Instanz. Wenn es sich dabei aufgrund der äußeren Umstände wirklich um eine SocketEx-Instanz handelt, kann es mit as einfach konvertiert werden. Dies hat außerdem den Vorteil, dass die as-Konvertierung im Fehlerfall null zurückliefert, ohne dass es zu einer Exception führt. Dies kann (besser: sollte in der Regel) vor der Fortsetzung geprüft werden.

Das besagte auch die obige Fehlermeldung:
Zitat:

Es ist eine explizite Konvertierung vorhanden. (Fehlt eine Umwandlung?)
nämlich "as" benutzen als explizite Konvertierung.

Gruß Jürgen

Das Problem ist eben, dass Accept() eben KEINE SocketEx Instanz zurückgibt, sondern nur eine Socket-Instanz. D.h. der Cast durch as liefert mir null.

Zitat:

Zitat von Khabarakh
Beschreibe doch einmal näher, was du mit deiner SocketEx-Klasse vorhast. Wenn es ein Wrapper werden soll, ist Vererbung der falsche Weg.

Ich weiß, dass es der falsche Weg wäre. Aber ich will im Prinzip der Socketklasse nur (im Moment) eine weitere Variable hinzufügen.

Phoenix 19. Jan 2009 12:35

Re: Typecasting in C#
 
Zitat:

Zitat von Neutral General
Ich weiß, dass es der falsche Weg wäre. Aber ich will im Prinzip der Socketklasse nur (im Moment) eine weitere Variable hinzufügen.

Du kannst Extension Methods dazu 'mißbrauchen'.

Grundidee:
Code:
public static class ValueHolder
{
   private static Dictionary<Object, String> _Values = new Dictionary<Object, String>();

   public static void SetValue(this Object obj, String value)
   {
      _Values.Add(obj, value);
   }

   public static String GetValue(this Object obj)
   {
      return _Values[obj];
   }

}
Das heisst Du hast zwei Extension Methods (getter und setter) und speicherst die Daten in einem Object-Value dictionary. Das Objekt selber nimmst Du als Schlüssel her. Somit geht das nicht nur auf dem Socket, sondern auf jedem beliebigen anderen Objekt auch.

Neutral General 19. Jan 2009 19:06

Re: Typecasting in C#
 
Hi,

Naja danke für den Code und den Ansatz, aber ich will in meinem Programm nicht zu rummurksen :mrgreen:

Der Code muss schon ordentlich werden. Ich muss mal gucken....

Phoenix 19. Jan 2009 19:14

Re: Typecasting in C#
 
Zitat:

Zitat von Neutral General
Naja danke für den Code und den Ansatz, aber ich will in meinem Programm nicht zu rummurksen :mrgreen:
Der Code muss schon ordentlich werden.

Das ist ordentlicher Code :)
Es gibt eben Dinge, die gehen ned anders. Es gibt eben leider kein ISocket Interface. Damit liesse sich sowas mittels Interface Delegation und Prism in ein paar Zeilen sehr elegant lösen. Aber Extension Methods sind durchaus legitim.

Dax 19. Jan 2009 19:41

Re: Typecasting in C#
 
Zitat:

Zitat von Phoenix
Es gibt eben Dinge, die gehen ned anders. Es gibt eben leider kein ISocket Interface. Damit liesse sich sowas mittels Interface Delegation und Prism in ein paar Zeilen sehr elegant lösen. Aber Extension Methods sind durchaus legitim.

Ja, schon, aber du verhinderst mit deinem Code effektiv die GC. Sowas müsste man auf deinem Weg dann über eine Map int -> List<Pair<WeakRef, String>> für Hashcode -> Zeugs machen.. Sonst ist das nicht ordentlich.

alzaimar 19. Jan 2009 21:21

Re: Typecasting in C#
 
Gibts in C# keine Class Helper? :gruebel: :mrgreen:

Neutral General 19. Jan 2009 21:26

Re: Typecasting in C#
 
Zitat:

Zitat von alzaimar
Gibts in C# keine Class Helper? :gruebel: :mrgreen:

Das hab ich mir auch schonmal gedacht -.-^^

Aber Class Helper können ja (leider) auch keine neuen Properties einführen :?

Phoenix 19. Jan 2009 21:27

Re: Typecasting in C#
 
Zitat:

Zitat von alzaimar
Gibts in C# keine Class Helper? :gruebel: :mrgreen:

Äh, die Extension Methods die ich gezeigt hab sind genau das.

Neutral General 19. Jan 2009 21:33

Re: Typecasting in C#
 
Mh.. Naja...

Aber "echte" Classhelper sind das nicht oder? Aufgerufen wird das ganze ja wie ich das sehe durch:

Code:
ValueHolder.SetValue(ASocket,"Value");
ooder?

alzaimar 19. Jan 2009 21:39

Re: Typecasting in C#
 
Oh, dann eine Decorator, den Du erweiterst (weiss nicht, wie das dann heißt). Was anderes fällt mir nicht ein.

Eine Socke(t) nun mal kein Kniestrumpf. Dazu ist er zu kurz.

@Phoenix: Dann hab ich das nicht kapiert. :drunken:

Dax 19. Jan 2009 21:54

Re: Typecasting in C#
 
Zitat:

Zitat von Neutral General
Aber "echte" Classhelper sind das nicht oder? Aufgerufen wird das ganze ja wie ich das sehe durch:

Code:
ValueHolder.SetValue(ASocket,"Value");
ooder?

Nein.
Code:
ASocket.SetValue("Value");
C#3+ vorrausgesetzt, natürlich.

Phoenix 19. Jan 2009 22:22

Re: Typecasting in C#
 
Zitat:

Zitat von alzaimar
@Phoenix: Dann hab ich das nicht kapiert. :drunken:

Das 'this' Keyword bei den C# Extension Methods sorgt dafür, dass man diese Methode auf allen Objekten aufrufen kann, die vom Typ des 'this'-Parameters (oder deren Ableitungen) sind.

Man muss dann nur noch die weiteren Parameter angeben.
Das hier ist meine Parade-Extension Method:
Code:
namespace smartDev.Extensions
{
   public static class StringExtender
   {
      public static Boolean IsEmpty(this String value)
      {
         return String.IsNullOrEmpty(value);
      }
   }
}
Und der Aufruf is dann eben:
Code:
if (myString.IsEmpty()) { myString = "Blubb"; }
Bedingung ist, dass der Namespace der Extension Method in der using-Klausel liegt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:57 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz