需要解决方法来限制 Facebook Flux 的 .NET 实现的虚拟抽象静态成员

Need workaround for restriction of virtual, abstract static members for .NET implementation of Facebook Flux

我看过 .NET 中的许多 Flux 实现,认为 this approach 相当不错:

也就是说,我想保留静态 属性-to-string 编码技术,但我无法进行以下工作:

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;
}

问题

您不能覆盖 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

这是一个 classical 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);

如果过于冗长,您始终可以在引用这些实例的基础 class 上声明静态成员:

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;(在其他 using namespace ... 声明中),这样使用站点就变成了:

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