views:

192

answers:

2

I am using the OracleClient library version 1.0.5000.0 and I am confused about the OracleParameter class and its implementation of ICloneable.

This is the definition of the OracleParameter class:

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

It implements System.ICloneable, but there is no Clone() method in there.

Can anyone explain this?

+4  A: 

In .NET you can explicitly implement interface members by using the following syntax:

object System.IClonable.Clone() { }

As a result you can only use the method by explicitly casting to the expected interface.

Also see http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oracleparameter.system.icloneable.clone%28VS.85%29.aspx

Mischa
Yeah, I'm starting to see that. So it doesn't appear in metadata? That's a dirty trick. You just have to "know" this stuff is there.
George Mauer
Sometimes this can be a good solution to have some required interfaces implemented but don't pollute intellisense.E.g. implementing Dispose() for the c# "using" syntax but give another "better" method for explicit calling e.g. "Close".
Mischa
Yeah I guess that's the answer but I don't know if I've ever seen such horrid API design. If you cache and try to reuse derived parameters it throws an error unless you clone them, but the method to clone is hidden unless you disassemble the class or just "know" it.I mean Oracle has never been a shining example of API design but this is downright malicious.
George Mauer
+2  A: 

This comes up from time to time. :) Check out the following ...

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()" );
  }
}
JP Alioto
Yeah I get it now, but why in the world would that not show up in metadata? That's just mean.
George Mauer
it could be an Ellison conspiracy. :) I'm actually kind of shocked that it does not. But, I am sure Reflector (http://www.red-gate.com/products/reflector/) will see it.
JP Alioto
Yeah, Reflector picked it up, but that is an insane bit of API. If you want to do anything useful with that class it seems like you HAVE to clone it, but that operation is nicely hidden from anyone that doesn't want to disassemble the code.
George Mauer