【问题标题】:Why does OracleParameter implement ICloneable but doesn't provide Clone()?为什么 OracleParameter 实现了 ICloneable 但不提供 Clone()?
【发布时间】:2009-08-25 21:23:32
【问题描述】:

我正在使用 OracleClient 库版本 1.0.5000.0,我对 OracleParameter 类及其 ICloneable 的实现感到困惑。

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

它实现了System.ICloneable,但是里面没有Clone()方法。

谁能解释一下?

【问题讨论】:

  • 你确定这是整个班级吗?你从哪里得到的代码?反光板?你确定你都看到了吗?
  • visual studio 2008 F12 - 所以来自元数据。嗯...反射器确实显示了有趣的对象 ICloneable.Clone()...

标签: c# .net oracleclient


【解决方案1】:

在 .NET 中,您可以使用以下语法显式实现接口成员:

对象 System.IClonable.Clone() { }

因此,您只能通过显式转换为预期接口来使用该方法。

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

【讨论】:

  • 是的,我开始看到了。所以它没有出现在元数据中?这是一个肮脏的把戏。你只需要“知道”这些东西就在那里。
  • 有时这可能是一个很好的解决方案,可以实现一些必需的接口,但不会污染智能感知。例如。为 c#“使用”语法实现 Dispose(),但为显式调用提供另一种“更好”的方法,例如“关闭”。
  • 是的,我想这就是答案,但我不知道我是否见过如此可怕的 API 设计。如果您缓存并尝试重用派生参数,除非您克隆它们,否则它会引发错误,但是除非您反汇编该类或只是“知道”它,否则要克隆的方法是隐藏的。我的意思是 Oracle 从来都不是 API 设计的光辉典范,但这是彻头彻尾的恶意。
【解决方案2】:

这不时出现。 :) 查看以下内容...

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

【讨论】:

  • 是的,我现在明白了,但是为什么这不会出现在元数据中呢?这只是卑鄙的。
  • 这可能是 Ellison 的阴谋。 :) 我实际上有点震惊,它没有。但是,我确信 Reflector (red-gate.com/products/reflector) 会看到它。
  • 是的,Reflector 捡到了它,但那是有点疯狂的 API。如果您想对该类做任何有用的事情,似乎您必须克隆它,但该操作对任何不想反汇编代码的人来说是隐藏的。
猜你喜欢
  • 2016-11-02
  • 2010-10-16
  • 2010-09-14
  • 2023-03-09
  • 2014-07-09
  • 2010-10-06
  • 1970-01-01
  • 2022-06-28
  • 1970-01-01
相关资源
最近更新 更多