各クライアントに (異なるアセンブリ バージョンで) 異なる列挙値を表示させたい場合、列挙型を使用するのは悪い解決策です。変更するとクライアント コードが壊れます...
列挙型の使用は機能する可能性があります (列挙型名とアセンブリ名が同じで、アセンブリが署名されていない限り) - アセンブリを交換するだけです。ただし、最後に存在しないコードのどこかで値が使用されている場合は、例外が発生します。また、値の異なるサブセットが異なる値に対して同じ番号になったり、同じ値に対して異なる番号になったりしないように、明示的に値に番号を付けることができます。
代わりに、リスト、辞書、データベース テーブルなど、動的に構築されたコレクションの使用を検討してください。または、列挙値の同じスーパーセットを持つ同じアセンブリをすべての人に提供し、ユーザーに関連する値を決定させます (おそらく、慣習として値に重要なプレフィックスを使用します)。
または、2つの組み合わせを使用できます...
サイトごとに異なる構造 (異なる型名 (または名前空間) とアセンブリ名) を (サイトのプロファイルに従って) 異なるプロパティで生成し、構造を受け入れるサービスの 1 つのマスター構造を生成します。すべての構造体に同じインターフェイスを実装してもらいます。これを受け取ると予想されます...
public interface IStatus
{
string GetKey();
}
public struct ClientXStatus : IStatus
{
private readonly string _key;
private ClientXStatus(string key)
{
_key = key;
}
// Don't forget default for structs is 0,
// therefore all structs should have a "0" property.
public ClientXStatus Default
{
get
{
return new ClientXStatus();
}
}
public ClientXStatus OptionB
{
get
{
return new ClientXStatus(10);
}
}
string IStatus.GetKey()
{
return _key;
}
public override bool Equals(object obj)
{
return (obj is IStatus) && ((IStatus)obj).GetKey() == _key;
}
public override int GetHashCode()
{
return _key.GetHashCode();
}
public static bool operator==(ClientXStatus x, IStatus y)
{
return x.Equals(y);
}
public static bool operator==(IStatus x, ClientXStatus y)
{
return y.Equals(x);
}
public static bool operator!=(ClientXStatus x, IStatus y)
{
return !x.Equals(y);
}
public static bool operator!=(IStatus x, ClientXStatus y)
{
return !y.Equals(x);
}
// Override Equals(), GetHashCode() and operators ==, !=
// So clients can compare structures to each other (to interface)
}
サービスのマスター構造体を使用します。
public struct MasterStatus : IStatus
{
private readonly string _key;
private MasterStatus(string key)
{
_key = key;
}
// Don't forget default for structs is 0,
// therefore all structs should have a "0" property.
public MasterStatus Default
{
get
{
return new MasterStatus();
}
}
// You should have all the options here
public MasterStatus OptionB
{
get
{
return new MasterStatus(10);
}
}
// Here use implicit interface implementation instead of explicit implementation
public string GetKey()
{
return _key;
}
public static implicit operator MasterStatus(IStatus value)
{
return new MasterStatus(value.GetKey());
}
public static implicit operator string(MasterStatus value)
{
return new value._key;
}
// Don't forget to implement Equals, GetHashCode,
// == and != like in the client structures
}
デモ サービス コード:
public void ServiceMethod(IStatus status)
{
switch (status.GetKey())
{
case (string)MasterStructA.OptionB:
DoSomething();
}
}
または:
public void ChangeStatus(IStatus status)
{
_status = (MasterStatus)status;
}
このようにして:
コード生成を使用して、値の衝突を防ぎます。
値を (非公開として) 非表示にし、構造体のみを受け入れることにより、ユーザーにコンパイル時チェック (int 値または文字列値なし) を使用するように強制します。
エラーが発生しやすいハックではなく、サービスのコード (インターフェイス) で実際のポリモーフィズムを使用します。
参照型ではなく、不変の値型 (列挙型など) を使用します。