简体   繁体   English

如何为属性定义虚拟getter和抽象setter?

[英]How to define a virtual getter and abstract setter for a property?

This is essentially what I want to do: 这基本上就是我想做的事情:

public abstract class Uniform<T>
{
    public readonly int Location;
    private T _variable;

    public virtual T Variable
    {
        get { return _variable; }
    }
}

public class UniformMatrix4 : Uniform<Matrix4>
{
    public override Matrix4 Variable
    {
        set
        {
            _variable = value;
            GL.UniformMatrix4(Location, false, ref _variable);
        }
    }
}

The getter for Variable will be the same across all derived classes, but the setter needs to be different. Variable的getter在所有派生类中都是相同的,但setter需要不同。

In fact... I'd prefer not to have derived classes at all (it's only one function call that will differ for each type) but I can't think of how else to do it. 事实上......我宁愿根本没有派生类(它只是一个函数调用,每种类型都会有所不同),但我想不出怎么做。


Edit: If it wasn't clear what the problem I'm having is, I'm getting a syntax error: 编辑:如果不清楚我遇到的问题是什么,我收到语法错误:

'UniformMatrix4.Variable.set': cannot override because 'Uniform.Variable' does not have an overridable set accessor 'UniformMatrix4.Variable.set':无法覆盖,因为'Uniform.Variable'没有可覆盖的set访问器

And I'm not sure how to create an "overridable set accessor"... virtual and abstract don't seem to be allowed on the setter. 而且我不确定如何创建一个“可覆盖的集合访问器”...... virtualabstract似乎不允许在setter上。

It's not possible to do this in C#, but as a workaround you could do this. 在C#中不可能这样做,但作为一种解决方法,你可以做到这一点。 It would involve calling an abstract setter function which could be overridden by derived classes, while leaving the standard get intact. 它将涉及调用一个抽象的setter函数,该函数可以被派生类覆盖,同时保持标准完整。 Would this work? 这会有用吗?

public abstract class Uniform<T>
{
    public readonly int Location;
    protected T _variable;

    public T Variable
    {
        get { return _variable; }
        set { SetVariable(value); } 
    }

    protected abstract void SetVariable(T value);
}

public class UniformMatrix4 : Uniform<Matrix4>
{
    public override void SetVariable(Matrix4x4 value)
    {
        _variable = value;
        GL.UniformMatrix4(Location, false, ref _variable);
    }
}

You will need to do this: 你需要这样做:

public abstract class Uniform<T>
{
    public readonly int Location;

    public virtual T Variable
    {
        get; set;
    }
}

public class UniformMatrix4 : Uniform<Matrix4>
{
    public override Matrix4 Variable
    {
        get
        {
            return base.Variable;
        }
        set
        {
            base.Variable = value;
            GL.UniformMatrix4(Location, false, ref value);
        }
    }
}

As I understand, the behaviour will be the expected. 据我了解,行为将是预期的。

Hope it helps. 希望能帮助到你。

It is not possible to do this in C#. 在C#中无法做到这一点。 You have to add a setter to the base class, and make it throw an "Invalid Operation" exception. 您必须将一个setter添加到基类,并使其抛出“无效操作”异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM