# C# Frage



## Guest (13. Okt 2006)

Hi,

kennt sich hier jemand zufällig in C# aus?
Wie kann man eigentlich den == Operator überladen und trotzdem
einen null-Vergleich bzw. einen Referenzvergleich machen?

Variante 1 (in so gut wie allen Büchern sieht es so aus)
	
	
	
	





```
class Foo
{
  private long id;

  public Foo(long id)
  {
    this.id = id;
  }

  public override bool Equals(object obj)
  {
    return this.id == ((Foo)obj).id; 
  }

  public static bool operator == (Foo obj1, Foo obj2)
  {
    return obj1.Equals(obj2); // Hier die Nullpointer-Exception, war ja auch klar
  }

  ...

}
```
Variante 2
	
	
	
	





```
class Foo
{
  private long id;

  public Foo(long id)
  {
    this.id = id;
  }

  public override bool Equals(object obj)
  {
    return this.id == ((Foo)obj).id;
  }

  public static bool operator == (Foo obj1, Foo obj2)
  {
    if(obj1 == null) // Hier die Endlosschleife
      return obj2 == null;
    if(obj2 == null)
      return false;
    return obj1.Equals(obj2);
  }

  ...

}
```
Wenn man es verwendet, dann passiert folgendes:
	
	
	
	





```
Foo a = new Foo(1);
Foo b = null;

Console.WriteLine(a == b); // Bei Variante 1 OK
Console.WriteLine(b == a); // Bei Variante 1 Nullpointer-Exception

Console.WriteLine(a == b); // Bei Variante 2 Endlosschleife
Console.WriteLine(b == a); // Bei Variante 2 Endlosschleife
```

Wie kann man da einen Referenzvergleich erzwingen?

Danke


----------



## Roar (13. Okt 2006)

Hi, hab zwar keine ahnung von C# bin aber pro-googler und als erstes ergebnis kam das: http://msdn2.microsoft.com/en-us/library/ms173147.aspx
ganz unten wird dein problem angesprochen vielleicht hilft's

ich verschieb das mal nach programmierung allgemein, für andere sprachen außer java ist das forum extra da.


----------



## Guest (13. Okt 2006)

Ohh ja, danke. Hat geholfen.
Mann, ist die Syntax krank. Man muss eine konkette Instanz zu object casten :autsch:, 
um einen Referenzvergleich zu machen (object implementiert einen Referenzvergleich) 
oder System.Object.ReferenceEquals(a,  b) verwenden. 

Bei C++ ist gleich klar, wo Pass-By-Value, wo Pass-By-Reference kommt. In Java sowieso. 
In C# ist es für mich nach einem Tag C# Turnen noch etwas unklar.  ???:L  :###


----------



## SnooP (13. Okt 2006)

Hmm... ohne, dass ich das jetzt direkt wusste, hätte ich auch vermutetet, dass du nach Object casten kannst, um über das equals von Object den Referenzvergleich zu bekommen. Das ist nämlich in Java absolut genauso... 
Also in sofern - so schlimm ist c# an der stelle nun nicht   -immerhin gibts die Möglichkeit Operatoren zu überladen schonmal.. ist doch für viele Anwendungen sicherlich ganz nett. Ich sach nur BigInteger...


----------



## Guest (14. Okt 2006)

SnooP hat gesagt.:
			
		

> Hmm... ohne, dass ich das jetzt direkt wusste, hätte ich auch vermutetet, dass du nach Object casten kannst, um über das equals von Object den Referenzvergleich zu bekommen. Das ist nämlich in Java absolut genauso...


Schön und gut, nur ist es ziemlich gefährlich, wenn ein Operator, je nach Cast, unterschiedlich reagiert.


----------



## RawBit (4. Nov 2006)

Roar hat gesagt.:
			
		

> Hi, hab zwar keine ahnung von C# bin aber pro-googler ....



rofl XD

an den vergleichen zu java ud c# code wird mal wieder klar wie sehr microsoft sich mühe gegeben hat die sprache EIGEN zumachen, ich mein zwischen 

@Override

und 

public override ...

is doch ein riesen unterschied oder


----------



## Illuvatar (4. Nov 2006)

Nur mal so:

a) C# ("override") war vor Java5 ("@Override")

b) override hat eine total andere Funktion als @Override. Das in Java ist nur eine Annotation, die dem (nicht unbedingt menschlichen) Leser sagt, dass da was überschrieben werden soll. Das in C# ist ein Schlüsselwort, das bedeutet, dass die virtuelle Methode überschrieben werden soll. Das gabs auch schon in C++, Delphi u.v.m., und - welch Wunder - es hieß da auch meistens irgendwas like override.

Ach ja, @SnooP: Was soll da in Java genauso sein? Da kann man keine Operatoren überladen - und in Java macht es eigentlich nie einen Unterschied ob man in Object castet, oder nicht...


----------



## RawBit (4. Nov 2006)

Illuvatar hat gesagt.:
			
		

> Nur mal so:
> 
> a) C# ("override") war vor Java5 ("@Override")
> 
> ...



lol, mein post sollte eigentlich nur ein scherz sein 

weil mi das grade so eingefalln is, ka warum, zu viel cola getrunken wahrscheinlich


----------



## Wildcard (4. Nov 2006)

Illuvatar hat gesagt.:
			
		

> in Java macht es eigentlich nie einen Unterschied ob man in Object castet, oder nicht...


Doch, beispielsweise bei überladenen Methoden tut es das.


----------



## byte (5. Nov 2006)

Was meinst Du denn damit? Wenn man eine Methode überlädt, dann ändert sich doch die Methodensignatur. Wenn ich dann nach Object caste, ist die überladene Methode doch gar nicht mehr sichtbar. Und bei überschriebenen Methoden ist es halt wie Illuvatar schon sagte egal, ob ich zu ner Vaterklasse hochcaste oder nicht, das ändert ja nichts daran, dass trotzdem die überschriebene Implementierung der Methode verwendet wird.


----------



## Beni (5. Nov 2006)

Wenn du 2 Methoden hast:

```
public void doSomething( Object o ){
  ...
}

public void doSomething( String s ){
  ...
}
```

Dann benötigst du einen Cast um die obere aufzurufen, wenn du eine String-Referenz besitzt:

```
String bla = "abc";

// hier werden verschiedene Methoden aufgerufen
doSomething( bla );
doSomething( (Object)bla );
```


----------



## byte (5. Nov 2006)

Achso, das war gemeint. Danke!


----------



## Illuvatar (5. Nov 2006)

Wildcard hat gesagt.:
			
		

> Illuvatar hat gesagt.:
> 
> 
> 
> ...



Grmlgrmlgrml deswegen doch das "eigentlich" - ich wollte meinen Post nicht unnötig verlängern


----------

