2009-08-25 9 views
4

J'utilise la bibliothèque OracleClient version 1.0.5000.0 et je suis confus au sujet de la classe OracleParameter et son implémentation de ICloneable.Pourquoi OracleParameter implémente ICloneable mais ne fournit pas Clone()?

Telle est la définition de la classe OracleParameter:

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(); 
} 

Il met en œuvre System.ICloneable, mais il n'y a pas de méthode Clone() là-dedans.

Quelqu'un peut-il expliquer cela?

+0

Êtes-vous sûr que c'est la classe entière? Où avez-vous reçu le code? Réflecteur? Vous êtes sûr de tout voir? – BFree

+0

studio visuel 2008 F12 - donc des métadonnées. Hmmm ... le réflecteur montre l'objet ICloneable.Clone() ce qui est intéressant ... –

Répondre

5

Dans .NET, vous pouvez explicitement mettre en œuvre les membres de l'interface en utilisant la syntaxe suivante:

System.IClonable.Clone objet() { }

Par conséquent, vous ne pouvez utiliser la méthode explicitement casting à l'interface attendue.

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

+0

Ouais, je commence à voir ça. Donc, il n'apparaît pas dans les métadonnées? C'est un truc sale. Vous devez juste "savoir" que ce truc est là. –

+1

Parfois, cela peut être une bonne solution pour que certaines interfaces requises soient implémentées mais ne polluent pas intellisense. E.g. mettre en oeuvre Dispose() pour la syntaxe C# "using" mais donner une autre "meilleure" méthode pour l'appel explicite, par ex. "Fermer". – Mischa

+1

Ouais je suppose que c'est la réponse mais je ne sais pas si j'ai déjà vu une conception d'API aussi horrible. Si vous mettez en cache et essayez de réutiliser les paramètres dérivés, une erreur est générée, sauf si vous les clonez, mais la méthode de clonage est masquée sauf si vous désassemblez la classe ou si vous la «connaissez». Je veux dire qu'Oracle n'a jamais été un brillant exemple de conception d'API, mais c'est carrément malveillant. –

2

Cela vient de temps en temps. :) Vérifiez les éléments suivants ...

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

Ouais je l'ai maintenant, mais pourquoi dans le monde cela n'apparaîtrait-il pas dans les métadonnées? C'est juste méchant. –

+0

ce pourrait être une conspiration d'Ellison. :) Je suis en fait un peu choqué que ce ne soit pas le cas. Mais, je suis sûr que Reflector (http://www.red-gate.com/products/reflector/) le verra. –

+0

Oui, Reflector l'a ramassé, mais c'est un peu fou d'API. Si vous voulez faire quelque chose d'utile avec cette classe, il semble que vous ayez à le cloner, mais cette opération est bien cachée à quiconque ne veut pas désassembler le code. –