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

时间:2017-08-13 14:32:21

标签: c# clr flux fody

我已经看过.NET中的一些Flux实现,并认为this approach非常膨胀:

  • 它使用静态成员而不是枚举,使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插件可以帮助(我没有看到一个)

2 个答案:

答案 0 :(得分:2)

您无法覆盖static成员,但可以使用new修饰符隐藏它们。对于exaple:

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

答案 1 :(得分: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;(在其他using namespace ...声明中),这样使用网站就会变成:

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