====== Das Diamant-Problem in C Sharp ======
Entgegen der landläufigen Meinung, dass ''interfaces'' in C Sharp vor dem Diamand-Problem schützen, reimplementiert das folgende Beispiellisting das Diamant-Problem, ohne dass C Sharp einen Hinweis auf ein mögliches Problem liefert. Der Quelltext kompiliert in Visual Studio ohne eine Warnung durch.
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
namespace DiamondTest
{
enum DiamondValue
{
Class_A_Value,
Class_C_Value
}
class DiamondData
{
public DiamondValue Value;
}
interface IDiamond
{
DiamondData DiamondData { get; }
}
class A : IDiamond
{
DiamondData _diamondData;
int _aData;
public A()
{
_diamondData = new DiamondData();
_diamondData.Value = DiamondValue.Class_A_Value;
}
public DiamondData DiamondData { get { return _diamondData; } }
}
class B : A
{
int _neverUsed;
public B()
{
_neverUsed = 0;
}
}
/* C soll IDiamond implementieren, dabei wird - wie bei der
* Mehrfachvererbung übersehen, dass eine andere Basisklasse
* - nämlich B - bereits mit einer Diamondimplementierung
* daherkommt.
*/
class C : B, IDiamond
{
/* kein new, kein override, kein Hinweis */
DiamondData _diamondData;
public C()
{
_diamondData = new DiamondData();
_diamondData.Value = DiamondValue.Class_C_Value;
}
/* kein new, kein override, kein Hinweis */
public DiamondData DiamondData { get { return _diamondData; } }
}
class Program
{
static void CompareDiamondDataValue(A a, C c)
{
MessageBox.Show("DiamondData Identisch?: "
+ (a.DiamondData.Value == c.DiamondData.Value).ToString());
}
static void Main(string[] args)
{
C c = new C();
/* Ich vergleiche zweimal das gleiche Objekt */
CompareDiamondDataValue(c, c);
}
}
}
Der entscheidene Punkt ist, dass bei
static void CompareDiamondDataValue(A a, C c)
{
MessageBox.Show("DiamondData Identisch?: "
+ (a.DiamondData.Value == c.DiamondData.Value).ToString());
}
für a und c das identische Objekt verwendet wird, aber a.DiamondData.Value eben nicht gleich mit c.DiamondData.Value ist, weil auf unterschiedliche Speicherbereiche zugegriffen wird, was für den Entwickler so aber nicht ersichtlich ist.