如何将常量与C#中的接口相关联?

Chr*_*isW 17 c# idl c++-cli webidl

有些语言允许您将常量与接口相关联:

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;
};
Run Code Online (Sandbox Code Playgroud)

我想定义这个接口,以便可以从C#调用它.

显然,C#无法定义与接口关联的常量.

  • 将此类接口转换为C#的常用方法是什么?
  • 是否有任何针对DOM接口的"规范"C#绑定?
  • 虽然C#不能,是否有另一种.NET语言可以定义与接口相关的常量?

Mat*_*vey 17

回答你的第三个问题:

虽然C#不能,是否有另一种.NET语言可以定义与接口相关的常量?

C++/CLI允许您literal在接口中定义值,这些static const值等同于C#中的值.

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;
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过C#访问这些值:

public static void Main()
{
    short primitiveValue = ICSSValue.CSS_PRIMITIVE_VALUE;

    Debug.Assert(primitiveValue == 1);
}
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅MSDN上的此页面.

免责声明:禁止在接口中使用常量值的设计决策很好.暴露实现细节的接口很可能是漏洞抽象.在这个例子中,CSS Value Type可能更适合作为枚举.

  • @kprobst我不同意你:) (3认同)
  • 虽然我很欣赏CLR允许你这样做,但是用C++编写接口只是为了能够在其中使用常量,这似乎是违反直觉的.但是没问题. (2认同)

Ser*_*rvy 14

如果你想要一个存储常量的地方,我会使用一个静态类:

public static class MyConstants
{
    public const int first = 1;
    public const int second = 2;
    public const string projectName = "Hello World";
}
Run Code Online (Sandbox Code Playgroud)

那是(至少一个)共同标准.

  • @ChrisW就像他们需要知道人工界面的名字一样......它没有任何不同. (3认同)
  • 客户端需要知道人工静态类的名称(或者,他们需要知道人工枚举类型的名称).该静态类的名称是否有任何"通用标准"? (2认同)

kpr*_*bst 7

C#不允许接口中的常量,因为常量是一个实现方面,理论上它不属于仅定义行为协议的类型.

我怀疑Java人员允许接口中的const字段,因为接口在内部被视为某种抽象类,或者因为他们需要它来弥补类型系统中的某些缺陷,比如枚举.

我不确定"DOM接口的规范绑定"是什么意思.C#不能在浏览器中运行.

也就是说,您需要将常量放在其他位置,例如结构或枚举(如果它们是数字).也许下面的某种命名约定将帮助-如果你的界面是IFooBar那么也许包含您的常量可以被称为结构IFooSetttingsIFooValues或什么是适当的.

我不知道除C#和VB.NET之外的任何CLR语言,但我很确定VB不允许这样做(尽管已经有一段时间了).

  • Java枚举比C#枚举更强大。实际上,它们是我在Java中唯一喜欢的东西。答案是因为他们被视为幕后的纯粹“抽象阶级”。W3C将DOM接口作为IDL发布,以便新的浏览器可以滚动自己的实现,同时仍然符合标准。 (2认同)
  • @ChrisW理论上是的.经过调查,我发现你可以在C++/CLI中的接口中定义文字值.`public interface class IExample {public:literal float Pi = 3.14159f}`这相当于一个`static const`变量. (2认同)

Dav*_*yde 7

我添加了“仅获取”属性,并在定义中使用const对其进行了备份。

public interface IFoo
{
    string ConstValue { get; }
}

public class Foo : IFoo
{
    public string ConstValue => _constValue;
    private string _constValue = "My constant";
}
Run Code Online (Sandbox Code Playgroud)


Gle*_*tle 7

C# 8 现在允许在interface定义中使用常量。

  • 如何?我使用的是 C# 8,“public const type name = value”语法编译失败,并显示“目标运行时不支持默认接口实现”。 (3认同)