如何将常量与 C# 中的接口相关联?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12752364/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to associate constants with an interface in C#?
提问by ChrisW
Some languages let you associate a constant with an interface:
某些语言允许您将常量与接口相关联:
The W3C abstract interfaces do the same, for example:
W3C 抽象接口也做同样的事情,例如:
// Introduced in DOM Level 2:
interface CSSValue {
// UnitTypes
const unsigned short CSS_INHERIT = 0;
const unsigned short CSS_PRIMITIVE_VALUE = 1;
const unsigned short CSS_VALUE_LIST = 2;
const unsigned short CSS_CUSTOM = 3;
attribute DOMString cssText;
attribute unsigned short cssValueType;
};
I want to define this interface such that it can be called from C#.
我想定义这个接口,以便它可以从 C# 调用。
Apparently C# cannot define a constant associated with an interface.
显然 C# 不能定义与接口关联的常量。
- What is the usual way to translate such an interface to C#?
- Are there any 'canonical' C# bindings for the DOM interfaces?
- Although C# cannot, is there another .NET language which can define constants associated with an interface?
- 将此类接口转换为 C# 的常用方法是什么?
- DOM 接口是否有任何“规范的”C# 绑定?
- 尽管 C# 不能,但是否有另一种 .NET 语言可以定义与接口关联的常量?
采纳答案by MattDavey
To answer your third question:
回答你的第三个问题:
Although C# cannot, is there another .NET language which can define constants associated with an interface?
尽管 C# 不能,但是否有另一种 .NET 语言可以定义与接口关联的常量?
C++/CLI allows you to define literalvalues in an interface, which are equivalent to static constvalues in C#.
C++/CLI 允许您literal在接口中定义值,这相当于static constC# 中的值。
public interface class ICSSValue
{
public:
literal short CSS_INHERIT = 0;
literal short CSS_PRIMITIVE_VALUE = 1;
literal short CSS_VALUE_LIST = 2;
literal short CSS_CSS_CUSTOM = 3;
property DOMString^ cssText;
property ushort cssValueType;
}
You could then access the values via C#:
然后您可以通过 C# 访问这些值:
public static void Main()
{
short primitiveValue = ICSSValue.CSS_PRIMITIVE_VALUE;
Debug.Assert(primitiveValue == 1);
}
See this page on MSDNfor more details.
有关更多详细信息,请参阅MSDN 上的此页面。
Disclaimer: The design decision to disallow constant values in interfaces was a good one. An interface which exposes implementation details is most likely a leaky abstraction. In this example CSS Value Type is probably better off being an enumeration.
免责声明:在接口中禁止常量值的设计决定是一个很好的决定。暴露实现细节的接口很可能是一个有漏洞的抽象。在这个例子中,CSS 值类型最好是枚举。
回答by Servy
If you want a place to store your constants I would use a static class:
如果你想要一个地方来存储你的常量,我会使用一个静态类:
public static class MyConstants
{
public const int first = 1;
public const int second = 2;
public const string projectName = "Hello World";
}
That is (at least one) common standard.
那是(至少一个)通用标准。
回答by kprobst
C# doesn't allow constants in interfaces because a constant is an implementation facet which theoretically does not belong in a type that only defines a behavior protocol.
C# 不允许在接口中使用常量,因为常量是一个实现方面,理论上它不属于仅定义行为协议的类型。
I suspect the Java folks allow const fields in interfaces either because an interface is treated internally as some kind of abstract class, or because they needed that to make up for some deficiency in the type system, like enums.
我怀疑 Java 人员允许接口中的 const 字段,要么是因为接口在内部被视为某种抽象类,要么是因为他们需要它来弥补类型系统中的某些缺陷,例如枚举。
I'm not sure what you mean by "canonical bindings for the DOM interfaces". C# does not run in a browser.
我不确定“DOM 接口的规范绑定”是什么意思。C# 不在浏览器中运行。
That said, you'll need to put your constants somewhere else, like a struct, or an enum (if they are numeric). Perhaps following some kind of naming convention would help -- if your interface is IFooBarthen maybe the struct that contains your constant could be called IFooSetttingsor IFooValuesor whatever is appropriate.
也就是说,您需要将常量放在其他地方,例如结构体或枚举(如果它们是数字)。也许下面的某种命名约定将帮助-如果你的界面是IFooBar那么也许包含您的常量可以被称为结构IFooSetttings或IFooValues或什么是适当的。
I don't know any CLR languages other than C# and VB.NET, but I'm pretty sure VB doesn't allow this (although it's been a while).
我不知道除了 C# 和 VB.NET 之外的任何 CLR 语言,但我很确定 VB 不允许这样做(尽管已经有一段时间了)。
回答by Chris F Carroll
An abstract class will do everything an interface will do (well, apart from pass a typeof(T).IsInterfacetest) and allow constants.
抽象类会做接口会做的所有事情(好吧,除了通过typeof(T).IsInterface测试)并允许使用常量。
The objection to constants (or enums) embedded in interfaces is misplaced. It's a naming issue. Naming constants in the very precise context where they have meaning is better than naming them out of context.
反对嵌入在接口中的常量(或枚举)是错误的。这是一个命名问题。在具有意义的非常精确的上下文中命名常量比在上下文之外命名它们更好。
回答by icar0
Try define it thought method parameters and/or returned values
尝试定义方法参数和/或返回值
public enum IFIleValue
{
F_OK = 0,
F_WRONG_NAME = -1,
F_ERROR_OBJECT_DATA = -2,
};
public interface IFile
{
IFIleValue New(String Name=null);
IFIleValue Open(String Path);
IFIleValue Save();
IFIleValue SaveAs(String Path);
IFIleValue Close();
}
回答by Jay Schroeder
I use SO all the time but this is my first ever post here. I found this post, trying to solve the same problem. When I saw the post on using a static class (by Servy) it got me thinking about solving this by embedding the Interface inside that static class.
我一直使用 SO,但这是我第一次在这里发帖。我找到了这篇文章,试图解决同样的问题。当我看到关于使用静态类的帖子(由 Servy)时,我开始考虑通过将接口嵌入到该静态类中来解决这个问题。
// define an interface with static content
public static class X {
// define the interface to implement
public interface Interface {
string GetX();
}
// static content available to all implementers of this interface
public static string StandardFormat(object x) {
return string.Format("Object = {0}", x.ToString());
}
}
// Implement the interface
public class MyX : X.Interface {
public override string ToString() {
return "MyX";
}
#region X.Interface Members
public string GetX() {
// use common code defined in the "interface"
return X.StandardFormat(this);
}
#endregion
}
回答by David Hyde
I added a Get only property and backed it up with a const in the definition.
我添加了一个 Get only 属性并在定义中使用 const 进行备份。
public interface IFoo
{
string ConstValue { get; }
}
public class Foo : IFoo
{
public string ConstValue => _constValue;
private string _constValue = "My constant";
}
回答by Michiel de Wolde
A custom attribute can be used:
可以使用自定义属性:
[Constant("CSS_INHERIT", 0)]
[Constant("CSS_PRIMITIVE_VALUE", 1)]
public interface BlaBla
The custom attribute class could look like:
自定义属性类可能如下所示:
[AttributeUsage(AttributeTargets.Interface, AllowMultiple = true, Inherited = false)]
public class ConstantAttribute: Attribute
{
public ConstantAttribute(string key, object value)
{
// ...
}
}
Constants can be retrieved using
可以使用检索常量
object[] attributes = typeof(BlaBla).GetCustomAttributes(typeof(ConstantAttribute),
inherit: false);

