2009-08-25 8 views
4

Ich verwende die OracleClient Bibliothek Version 1.0.5000.0 und ich bin verwirrt über die OracleParameter Klasse und ihre Implementierung von ICloneable. Warum implementiert OracleParameter ICloneable, aber Clone() nicht?

Dies ist die Definition der OracleParameter Klasse:

public sealed class OracleParameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable { 
    public OracleParameter(); 
    public OracleParameter(string name, object value); 
    public OracleParameter(string name, OracleType oracleType); 
    public OracleParameter(string name, OracleType oracleType, int size); 
    public OracleParameter(string name, OracleType oracleType, int size, string srcColumn); 
    public OracleParameter(string name, OracleType oracleType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, string srcColumn, DataRowVersion srcVersion, object value); 

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
    [RefreshProperties(RefreshProperties.All)] 
    [Browsable(false)] 
    public DbType DbType { get; set; } 
    [RefreshProperties(RefreshProperties.All)] 
    public ParameterDirection Direction { get; set; } 
    [Browsable(false)] 
    [DesignOnly(true)] 
    [EditorBrowsable(EditorBrowsableState.Never)] 
    [DefaultValue(false)] 
    public bool IsNullable { get; set; } 
    [DefaultValue(0)] 
    [Browsable(false)] 
    public int Offset { get; set; } 
    [RefreshProperties(RefreshProperties.All)] 
    public OracleType OracleType { get; set; } 
    [DefaultValue("")] 
    public string ParameterName { get; set; } 
    [DefaultValue(0)] 
    public byte Precision { get; set; } 
    [DefaultValue(0)] 
    public byte Scale { get; set; } 
    [DefaultValue(0)] 
    public int Size { get; set; } 
    [DefaultValue("")] 
    public string SourceColumn { get; set; } 
    public DataRowVersion SourceVersion { get; set; } 
    [DefaultValue("")] 
    [RefreshProperties(RefreshProperties.All)] 
    [TypeConverter(typeof(StringConverter))] 
    public object Value { get; set; } 

    public override string ToString(); 
} 

Es implementiert System.ICloneable, aber es gibt keine Clone() Methode drin.

Kann jemand das erklären?

+0

Sind Sie sicher, dass das die gesamte Klasse ist? Woher hast du den Code? Reflektor? Bist du sicher, dass du alles siehst? – BFree

+0

Visual Studio 2008 F12 - so aus Metadaten. Hmmm ... Reflektor zeigt Objekt ICloneable.Clone() das ist interessant ... –

Antwort

5

In .NET Sie explizit Schnittstelle Mitglieder mit folgenden Syntax implementieren können:

Objekt System.IClonable.Clone() { }

Als Ergebnis erhalten Sie nur die Methode explizit verwenden können Casting an die erwartete Schnittstelle.

Siehe auch http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oracleparameter.system.icloneable.clone(VS.85).aspx

+0

Ja, ich fange an, das zu sehen. Es erscheint also nicht in Metadaten? Das ist ein schmutziger Trick. Sie müssen nur wissen, dass das Zeug da ist. –

+1

Manchmal kann dies eine gute Lösung sein, um einige erforderliche Schnittstellen implementiert zu haben, aber intellisense nicht zu verschmutzen. Zum Beispiel Implementieren von Dispose() für die C# "using" -Syntax, aber eine andere "bessere" Methode zum expliziten Aufruf von z. "Schließen". – Mischa

+1

Ja, ich denke, das ist die Antwort, aber ich weiß nicht, ob ich jemals solch schrecklichen API-Design gesehen habe. Wenn Sie abgeleitete Parameter zwischenspeichern und versuchen, sie wiederzuverwenden, wird ein Fehler ausgegeben, es sei denn, Sie klonen sie, aber die zu klonende Methode ist verborgen, es sei denn, Sie zerlegen die Klasse oder "kennen" sie einfach. Ich meine, Oracle war nie ein leuchtendes Beispiel für API-Design, aber das ist geradezu bösartig. –

2

Dies kommt zu Zeit von Zeit. :) Überprüfen Sie die folgenden ...

void Main() 
{ 
    var e = new Example(); 
    I i = e as I; 

    e.m1(); // prints Class m1() 
    i.m1(); // prints Interface m1() 
} 

public interface I 
{ 
    void m1(); 
} 

public class Example : I 
{ 
    public void m1() 
    { 
    Console.WriteLine("Class m1()"); 
    } 

    void I.m1() 
    { 
    Console.WriteLine("Interface m1()"); 
    } 
} 
+0

Ja, ich verstehe es jetzt, aber warum in der Welt würde das nicht in Metadaten erscheinen? Das ist einfach gemein. –

+0

könnte es eine Verschwörung von Ellison sein. :) Ich bin eigentlich schockiert, dass es nicht so ist. Aber ich bin mir sicher, Reflector (http://www.red-gate.com/products/reflector/) wird es sehen. –

+0

Ja, Reflektor hat es aufgegriffen, aber das ist eine wahnsinnige API. Wenn Sie etwas Nützliches mit dieser Klasse machen wollen, scheint es, als müssten Sie es klonen, aber diese Operation ist für jeden, der den Code nicht zerlegen möchte, gut versteckt. –