一部の言語では、定数をインターフェイスに関連付けることができます。
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;
};
C#から呼び出せるようにこのインターフェイスを定義したいと思います。
どうやらC#はインターフェイスに関連付けられた定数を定義できません。
3番目の質問に答えるには:
C#ではできませんが、インターフェイスに関連付けられた定数を定義できる別の.NET言語はありますか?
C++/CLIでは、インターフェイスでliteral
値を定義できます。これは、C#のstatic const
値に相当します。
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;
}
その後、C#を介して値にアクセスできます。
public static void Main()
{
short primitiveValue = ICSSValue.CSS_PRIMITIVE_VALUE;
Debug.Assert(primitiveValue == 1);
}
詳細は MSDNのこのページ を参照してください。
免責事項:インターフェイスで定数値を許可しないという設計上の決定は良いものでした。実装の詳細を公開するインターフェースは、おそらくリークの多い抽象化です。この例では、CSS値タイプはおそらく列挙である方が良いでしょう。
定数を保存する場所が必要な場合は、静的クラスを使用します。
public static class MyConstants
{
public const int first = 1;
public const int second = 2;
public const string projectName = "Hello World";
}
これが(少なくとも1つの)共通の標準です。
定数は、動作プロトコルのみを定義する型には理論的には属さない実装ファセットであるため、C#ではインターフェイスで定数を使用できません。
私はJava=人々がインターフェイスでconstフィールドを許可していると思います列挙型。
「DOMインターフェースの標準的なバインディング」の意味がわかりません。 C#はブラウザーでは実行されません。
つまり、定数は構造体や列挙型(数値の場合)などの別の場所に配置する必要があります。おそらく、ある種の命名規則に従うことが役立つでしょう。インターフェイスがIFooBar
の場合、定数を含む構造体はIFooSetttings
またはIFooValues
または適切なものと呼ばれる可能性があります。
C#とVB.NET以外のCLR言語は知りませんが、VBはこれを許可していません(しばらくの間ですが)。
Get onlyプロパティを追加し、定義のconstでバックアップしました。
public interface IFoo
{
string ConstValue { get; }
}
public class Foo : IFoo
{
public string ConstValue => _constValue;
private string _constValue = "My constant";
}
私は常に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
}
抽象クラスは、インターフェイスが行うすべてのことを行い(typeof(T).IsInterface
テストをパスすることを除いて)、定数を許可します。
インターフェースに埋め込まれた定数(または列挙型)への反対は見当違いです。それは命名の問題です。定数が意味を持つ非常に正確なコンテキストで定数に名前を付けることは、コンテキスト外で名前を付けるよりも優れています。
カスタム属性を使用できます。
[Constant("CSS_INHERIT", 0)]
[Constant("CSS_PRIMITIVE_VALUE", 1)]
public interface BlaBla
カスタム属性クラスは次のようになります。
[AttributeUsage(AttributeTargets.Interface, AllowMultiple = true, Inherited = false)]
public class ConstantAttribute: Attribute
{
public ConstantAttribute(string key, object value)
{
// ...
}
}
定数は、
object[] attributes = typeof(BlaBla).GetCustomAttributes(typeof(ConstantAttribute),
inherit: false);
メソッドパラメータや戻り値を考慮して定義してみてください
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();
}