需要解决方法来限制 Facebook Flux 的 .NET 实现的虚拟抽象静态成员
Need workaround for restriction of virtual, abstract static members for .NET implementation of Facebook Flux
我看过 .NET 中的许多 Flux 实现,认为 this approach 相当不错:
- 它使用静态成员而不是枚举,XAML 更好
- 无需转换 to/from 枚举类型(代码更简洁)
- 与几乎所有 pub/sub 机制轻松集成。
也就是说,我想保留静态 属性-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;
}
问题
- 语言中是否有允许这样做的内容?
- 是否有任何我可以执行的预编译脚本允许这样做?
- 有没有我可以使用的 Fody 插件可以提供帮助(我没看到)
您不能覆盖 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);
我看过 .NET 中的许多 Flux 实现,认为 this approach 相当不错:
- 它使用静态成员而不是枚举,XAML 更好
- 无需转换 to/from 枚举类型(代码更简洁)
- 与几乎所有 pub/sub 机制轻松集成。
也就是说,我想保留静态 属性-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;
}
问题
- 语言中是否有允许这样做的内容?
- 是否有任何我可以执行的预编译脚本允许这样做?
- 有没有我可以使用的 Fody 插件可以提供帮助(我没看到)
您不能覆盖 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);