【问题标题】:Late Dynamic Binding variable type mismatch后期动态绑定变量类型不匹配
【发布时间】:2011-04-07 02:38:13
【问题描述】:

我给出的示例并不完全是我正在研究的内容,但它是一个近似表示,并且大大简化了确切的问题。我愿意调查所有选项。

我有一个抽象类,其数据值要在后续类中覆盖。

基础抽象类

public abstract class Variable
{
    public abstract long data;
}

我有一个子类

public class FloatVariable : Variable
{
    public override float data;
}

但是在使用后期动态绑定时我遇到了麻烦

Variable var = new FloatVariable();
var.data = 0.33f;

导致“无法将类型'float'隐式转换为'long'”的错误

显然我做得不对,但是如果有办法覆盖变量(和类型),以便后期动态绑定仍然允许它编译,它会让我的生活变得更轻松。

【问题讨论】:

  • 你的类不会编译。你的问题没有意义。而且您没有使用动态绑定。
  • “后期动态绑定”?还有“后期静态绑定”和“早期动态绑定”吗?
  • 我意识到后期动态绑定是一个 C++ 术语。这里的概念是我的子类可以覆盖变量,当我使用动态绑定时它不会默认为父变量类型,而是使用子变量类型。
  • 您不应该使用override 来覆盖数据类型。如果data 变量是必需的,请尝试使用public new float data;。但是,请注意,您很可能会混淆您自己和此代码的未来维护者。
  • 我刚刚尝试了new 关键字,但没有成功。

标签: c# oop inheritance abstract-class


【解决方案1】:

使用泛型可能会更好:

public class Variable<T>
{
    public T data;
}

那你就可以了

Variable var = new Variable<float>();
var.data = 0.33f;

【讨论】:

  • 我完全忘记了模板,这将是相当多的代码重写,但我会尝试并接受它,如果它有效,谢谢
  • 好吧,这几乎是完美的,但是我没有提到我的一种类型有一个嵌套的变量循环。在内部,它使用 List ,因为 SuperBaseClass 现在是我上面的“变量”类的父级,这样我就可以避免嵌套问题,但是 SuperBaseClass 不再有数据,再次导致问题。你怎么看?
  • 如果您可以添加此“变量嵌套循环”的代码,这将非常有用,这样我们就可以准确地完成您想要做的事情。
  • 好吧,我想我可以尝试使用联合,将值“处理”为更像 perl 中的标量类型。
【解决方案2】:

来自http://msdn.microsoft.com/en-us/library/ebca9ah3(v=vs.80).aspx:

“重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称,并且重写属性必须是虚拟的、抽象的或重写的。”

因此,您不能将类型从 long 更改为 float。

【讨论】:

    【解决方案3】:

    我找到了一个解决方案,可以解决我无法使用泛型/模板解决的问题。

    创建一个新的标量类

    Class Scalar
    {
        private byte dataByte = 0;
        private short dataShort = 0;
        // ... int, long, float, double
        private string dataString = 0;
        private List<Variable> dataList = null;
    
        //constructors for "later" type casting (see below)
        public Scalar(byte data)
        {
            this.dataByte = data;
        }
    
        //* repeat this for short, int, long, float, double, string, List<>
    
        //implicit conversions for getting data out
        public static implicit operator byte(Scalar scalar)
        {
            return scalar.dataByte;
        }
    
        //* repeat this for short, int, long, float, double, string, List<>
    
        //implicit conversions for getting data in (invokes a constructor)
        public static implicit operator Scalar(byte data)
        {
            return new Scalar(data);
        }
    
        //* repeat this for short, int, long, float, double, string, List<>
    }
    

    然后创建我的基变量类

    abstract class Variable
    {
        public Scalar Data
        {
            get { return data; }
            set { data = value; }
        }
    
        protected Scalar data = new Scalar(0);
    
        /* other meta information etc */
    }
    

    然后创建元变量的子类

    class MetaByte : Variable
    {
        public byte Data
        {
            get { return data; }
            set { data = value; }
        }
    
        /* byte specific features */
    }
    

    然后将它与动态绑定一起使用就可以了

    Variable scalar = new MetaByte();
    scalar.Data = 33;
    scalar = new MetaList();
    scalar.Data = new List<Variable>();
    

    它与列表并不完美,但它似乎适用于我打算如何使用它。

    【讨论】:

      猜你喜欢
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多