带有字段的摘要 class 被认为不是一个好的做法吗?
Is an abstract class with fields considered not a good practice?
我创建了一个实现接口的抽象 class。这个抽象 class 将成为需要填充该接口属性的几个具体 classes 的基础。
前两个示例弹出 CLR 合规性警告。我明白它们代表什么,这里有几个问题涵盖了它们。
为了使字段不同,我可以添加尾随下划线。它被编译器接受。这是正确的样式选择吗?我认为它不太突出,可能是一种代码味道。不过我可能就是不习惯。
或者我创建定义 属性 字段的抽象祖先是错误的吗?当然,这个想法是为了节省重复工作并帮助实施标准实施,但我可以看到,当它开始为这些 "hidden" 字段赋值时,它可能在后代中有自己的味道。
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;
}
}
}
抽象地制作受保护的字段是绝对可以接受的类。
命名约定仅供参考,具体取决于您使用的样式工具。使用您 and/or 您的团队喜欢的风格,并从中自定义您的工具。最重要的是项目本身是一致的。
我个人以前从未见过使用尾随下划线,但我可以看到它的好处。可能是显示受保护字段的一种非常聪明的方式。如果我 运行 加入使用它的团队,我肯定会赞成该约定。
必须创建一个抽象基础 class 只是为了避免重复定义三个字段不是代码味道,但是:
- 确实感觉像是把 DRY 发挥到了极致,
- 并且(假设您在其他地方使用继承),您阻止了从其他 classes 继承的机会。
但是,如果您willing/able使用 VS2015 和 C# 6,帮助就在眼前。新的只读自动属性允许您执行此操作,无需重复即可删除基数 class:
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 得到更广泛采用之前,您只能在继承和重复自己之间做出选择。
我创建了一个实现接口的抽象 class。这个抽象 class 将成为需要填充该接口属性的几个具体 classes 的基础。
前两个示例弹出 CLR 合规性警告。我明白它们代表什么,这里有几个问题涵盖了它们。
为了使字段不同,我可以添加尾随下划线。它被编译器接受。这是正确的样式选择吗?我认为它不太突出,可能是一种代码味道。不过我可能就是不习惯。
或者我创建定义 属性 字段的抽象祖先是错误的吗?当然,这个想法是为了节省重复工作并帮助实施标准实施,但我可以看到,当它开始为这些 "hidden" 字段赋值时,它可能在后代中有自己的味道。
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;
}
}
}
抽象地制作受保护的字段是绝对可以接受的类。
命名约定仅供参考,具体取决于您使用的样式工具。使用您 and/or 您的团队喜欢的风格,并从中自定义您的工具。最重要的是项目本身是一致的。
我个人以前从未见过使用尾随下划线,但我可以看到它的好处。可能是显示受保护字段的一种非常聪明的方式。如果我 运行 加入使用它的团队,我肯定会赞成该约定。
必须创建一个抽象基础 class 只是为了避免重复定义三个字段不是代码味道,但是:
- 确实感觉像是把 DRY 发挥到了极致,
- 并且(假设您在其他地方使用继承),您阻止了从其他 classes 继承的机会。
但是,如果您willing/able使用 VS2015 和 C# 6,帮助就在眼前。新的只读自动属性允许您执行此操作,无需重复即可删除基数 class:
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 得到更广泛采用之前,您只能在继承和重复自己之间做出选择。