I’m trying to code DRY, and I have the following setup, which Visual Studio’s Code Analysis system is telling me is unwise:
public abstract class ShaderBase
{
protected ShaderBase(Device device, string vertexShaderString, string pixelShaderString)
{
ShaderSignature inputSignature;
using (ShaderBytecode bytecode = ShaderBytecode.CompileFromFile(vertexShaderString, "VShader", "vs_4_0", ShaderFlags.None, EffectFlags.None))
{
vertexShader = new VertexShader(device, bytecode);
inputSignature = ShaderSignature.GetInputSignature(bytecode);
}
inputLayout = MakeInputLayout(device,inputSignature);
}
protected abstract InputLayout MakeInputLayout(Device device, ShaderSignature inputSignature);
}
public class TextureShader:ShaderBase
{
public ColourShader(Device device) : base(device,"shaders/colour.fx", "shaders/colour.fx")
{
}
protected override InputLayout MakeInputLayout(Device device, SlimDX.D3DCompiler.ShaderSignature inputSignature)
{
return new InputLayout(device, inputSignature, new[] {
new InputElement("POSITION", 0, SlimDX.DXGI.Format.R32G32B32_Float, 0),
new InputElement("COLOR",0,SlimDX.DXGI.Format.R32G32B32_Float,0)
});
}
}
So as you can see, I have a base class, from which I have multiple derived classes. Each derived class uses a different InputLayout and must therefore use a different implementation of MakeInputLayout, which is why I override it. However, every derived class must execute the code I’ve put in the base class’s constructor, including the call to whichever implementation of MakeInputLayout that derived class has.
I’m trying to avoid code duplication where possible, but Microsoft is suggesting I should never be calling overrideable functions in base class constructors, even though none of the overriden implementations ever depend on values set up at runtime (they could, technically, have been labelled static, if c# allowed us to override statics).
What I want to know is, what’s the acceptable way of having a base class force derived classes to call their own derived implementation of a function in their constructors? Or am I just going to have to copy and past some code around and reduce the maintainability of the system?
You can ignore Visual Studio’s Code Analysis, if you 100% sure that it will not be a problem in your case. However, it might be not very safety and personally I do not recomend to do so.
Use helper interfaces/classes/delegates to avoid constructor virtual method call: