我创建了一个实现接口的抽象类。这个抽象类将是几个需要填充该接口属性的具体类的基础。
CLR遵从性警告会在前两个示例中弹出。我明白它们代表什么,这里有几个问题涉及到它们。
为了使字段不同,我可以添加一个下划线。它被编译器接受。这是一个正确的风格选择吗?我不认为它很明显,可能是一种代码气味。但我可能只是不习惯。
或者我做一个定义属性字段的抽象祖先是错的吗?当然,这个想法是为了节省重复的工作,并帮助执行标准实现,但是我可以看到,当它开始为这些"隐藏"字段赋值时,它可能在后代中有自己的味道。
namespace MyLittleCompany.Widgety
{
public abstract class MlcWidgetInformation : IMlcWidgetInformation
{
//Compiler complains of Non-CLR Compliance (case difference only)
protected int sides; //Number of sides for this widget
//Compiler complains of Non-CLR Compliance (non-private name with underscore
// is not compliant)
protected int _hooks; //Number of hooks on this widget
//Compiler is happy with a trailing underscore
protected int feathers_; //Number of feathers on this widget
// Interface items
public Sides { get { return sides; } }
public Hooks { get { return _hooks; } }
public Feathers { get { return feathers_; } }
}
}
=====================================
namespace MyLittleCompany.Widgety
{
public class SmallWidgetInformation : MlcWidgetInformation
{
public SmallWidgetInformation()
{
// Is this a smell? As in "What are these things?"
sides = 6;
_hooks = 3;
feathers_ = 1;
}
}
}
创建抽象基类只是为了避免重复定义三个字段,这不是代码气味,但是:
- 感觉就像把DRY发挥到极致,
- 和(假设您在其他地方使用继承),您阻止了从其他类继承的机会。
然而,如果你愿意/能够使用VS2015和c# 6,帮助就在手边。新的只读auto属性允许您这样做,不需要重复基类:
public interface IMlcWidgetInformation
{
int Sides { get; }
int Hooks { get; }
int Feathers { get; }
}
public class SmallWidgetInformation : IMlcWidgetInformation
{
public int Sides { get; } = 6;
public int Hooks { get; } = 3;
public int Feathers { get; } = 1;
}
在c# 6被广泛采用之前,你只能在继承和重复之间做出选择。
在抽象类中创建受保护的字段是完全可以接受的。
命名约定只是指导原则,它取决于你正在使用的样式工具。使用您和/或您的团队喜欢的样式,并以此自定义您的工具。最重要的是项目本身是一致的。
我个人以前从未见过末尾下划线的使用,但我可以看到它的好处。这可能是显示受保护区域的一个很聪明的方法。如果我遇到一个使用这种惯例的团队,我肯定会赞成这种惯例。