如果您希望每个客户端看到不同的枚举值(在不同的程序集版本中),那么使用枚举是一个糟糕的解决方案 - 更改会破坏客户端代码......
使用枚举可能有效(只要枚举名称和程序集名称相同并且程序集未签名) - 您可以交换程序集。但是,如果在代码中的任何地方使用了最后不存在的值,则最终会出现异常。此外,您可能对值进行显式编号,以确保值的不同子集不会以不同值的相同数字或相同值的不同数字结束。
而是考虑使用动态构建的集合,例如列表、字典或数据库表。或者只是为每个人提供具有相同枚举值超集的相同程序集,让用户决定哪些值与他们相关(也许使用重要的值前缀作为约定)。
或者你可以使用两者的组合......
为每个站点生成不同的结构(不同的类型名称(或命名空间)和程序集名称),具有不同的属性(根据站点的配置文件)和一个接受这些结构的服务的主结构。让所有结构都实现相同的接口,您希望收到...
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 值或字符串值)。
在服务的代码(接口)中使用真正的多态性,而不是容易出错的 hack。
使用不可变值类型(如枚举)而不是引用类型。