2

我查看了 .NET 中的许多 Flux 实现,并认为这种方法非常好:

  • 它使用静态成员而不是枚举,使 XAML 更好
  • 无需转换为枚举类型/从枚举类型转换(更简洁的代码)
  • 与几乎所有发布/订阅机制轻松集成。

话虽如此,我想保留静态属性到字符串的编码技术,但我无法进行以下工作:

public class BitnameTypesBase
{
   // I want to override this in base classes.. but can't 
    public static string ChainName;

    public static string GET_BITNAME = "get_bitname_" + ChainName;
    public static string SEND_BITNAME = "send_bitname_" + ChainName;
    public static string QUERY_BITNAME = "query_bitname_" + ChainName;
}

public class BitcoinBitName :  BitnameTypesBase
{
   // Ouch, can't override field or properties 
    override public static string ChainName = "Bitcoin";

    public static string MySpecialAction = "special_bitname_" + ChainName;
}

public class OthercoinBitName :  BitnameTypesBase
{
   // Ouch, can't override field or properties
    override public static string ChainName = "something new";

    public static string MySpecialAction = "special_bitname_" + ChainName;
}

问题

  • 语言中有什么允许这样做的吗?
  • 是否有任何我可以做的预编译脚本允许这样做?
  • 是否有任何我可以使用的 Fody 插件可以提供帮助(我没有看到)
4

2 回答 2

2

您不能覆盖static成员,但可以使用new修饰符隐藏它们。例如:

public class BitnameTypesBase
{
    public static string ChainName;

    public static string GET_BITNAME = "get_bitname_" + ChainName;
    public static string SEND_BITNAME = "send_bitname_" + ChainName;
    public static string QUERY_BITNAME = "query_bitname_" + ChainName;
}

public class BitcoinBitName :  BitnameTypesBase
{
    public static new string ChainName = "Bitcoin";
    public static string MySpecialAction = "special_bitname_" + ChainName;
}

public class OthercoinBitName : BitnameTypesBase
{
    public static new string ChainName = "something new";
    public static string MySpecialAction = "special_bitname_" + ChainName;
}

现在:

Console.WriteLine(BitcoinBitName.MySpecialAction);
Console.WriteLine(OthercoinBitName.MySpecialAction);

将输出:

special_bitname_Bitcoin
special_bitname_something new
于 2017-08-13T14:42:14.080 回答
2

这是一个经典的 OO 选项(我经常使用这种模式):

public abstract class BitnameTypesBase
{
    public abstract string ChainName { get; }

    public string GET_BITNAME => "get_bit_name" + ChainName;
    public string SEND_BITNAME => "send_bitname_" + ChainName;
    public string QUERY_BITNAME => "query_bitname_" + ChainName;

    public virtual string MySpecialAction => "special_bitname_" + ChainName;

    public abstract class Of<T> : BitnameTypesBase where T : BitnameTypesBase, new()
    {
        public readonly static T Instance = new T();
    }
}

public sealed class BitcoinBitName : BitnameTypesBase.Of<BitcoinBitName>
{
    public override string ChainName= > "bitcoin";
}

public sealed class OthercoinName : BitnameTypesBase.Of<OthercoinName>
{
    public override string ChainName => "something new";
}

//other coins defined similarly

然后,你像这样使用:

Console.WriteLine(BitnameTypesBase.Of<BitcoinBitName>.Instance.MySpecialAction);
Console.WriteLine(BitnameTypesBase.Of<OthercoinName>.Instance.MySpecialAction);

如果详细程度有点高,您总是可以在引用这些实例的基类上声明静态成员:

public abstract class  BitnameTypesBase
{
    BitnameTypeBase Bitcoin = Of<BitcoinBitName>.Instance;
    BitnameTypeBase Othercoin = Of<OthercoinName>.Instance;

    //the rest of the class as defined before

}

那么使用站点就变成了:

Console.WriteLine(BitnameTypesBase.Bitcoin.MySpecialAction);
Console.WriteLine(BitnameTypesBase.Othercoin.MySpecialAction);

更好的是:如果您使用的是 C# 6 或更高版本,那么您可以using static BitnameTypesBase;在文件顶部添加 a(在其他using namespace ...声明中),因此使用站点变为:

Console.WriteLine(Bitcoin.MySpecialAction);
Console.WriteLine(Othercoin.MySpecialAction);
于 2017-08-13T15:51:54.340 回答