- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一系列静态类,用于获取枚举值的字符串。它们看起来都像这样:
public static class MyEnumToString
{
private static Dictionary<MyEnum, string> map
= new Dictionary<MyEnum, string>();
public static string Get(MyEnum type)
{
PopulateEmptyMap();
return map[type];
}
static void PopulateEmptyMap()
{
if (!map.Any())
{
PopulateMap();
}
}
private static void PopulateMap()
{
map[MyEnum.enum1] = "string for enum 1";
map[MyEnum.enum2] = "string for enum 2";
}
}
我有多个这样的类,它们使用的枚举类型和字符串值不同。显然,我应该合并这些类以减少重复代码。
我尝试做的是创建通用基类,以便它可以处理任何类型,然后为继承的类实现 PopulateMap。如果可能的话,它看起来像这样:
public static class TypeToString<TType>
{
public static Dictionary<TType, string> map
= new Dictionary<TType, string>();
public static string Get(TType type)
{
PopulateEmptyMap();
return map[type];
}
static void PopulateEmptyMap()
{
if (!map.Any())
{
PopulateMap();
}
}
public abstract static void PopulateMap();
}
public static class MyEnumToString: TypeToString<MyEnum>
{
public static void PopulateMap()
{
map[MyEnum.enum1] = "string for enum 1";
map[MyEnum.enum2] = "string for enum 2";
}
}
我必须公开 Dictionary 和 PopulateMap 方法,因为显然泛型类不能有 protected 或 protected 内部成员。必须公开这一点并不理想,但不会破坏交易。
我被挂断的是“可重写的方法不能是静态的”这一事实,因此我的 PopulateMap 方法不能既是抽象的又是静态的。如果它不是静态的,就不能从其他静态方法中调用它。如果它不是抽象的,则不会调用继承类的 PopulateMap。
这个版本甚至没有构建。
有什么方法可以做我正在尝试做的事情并且仍然保持我的类静态?我真的很想避免每次调用 TypeToString.Get() 时都必须有一个实例化的 TypeToString 对象。
最佳答案
这是一个方便的扩展方法,因为我猜您正在尝试将一些描述文本映射到枚举值:
public static class EnumExtensions
{
public static string GetDescription(this Enum value)
{
var field = value.GetType().GetField(value.ToString());
if (field == null)
return value.ToString();
var attribute = field.GetCustomAttributes(typeof(DescriptionAttribute), false)
.OfType<DescriptionAttribute>()
.SingleOrDefault();
return attribute != null
? attribute.Description
: value.ToString();
}
}
像这样使用它:
public enum Foo
{
[Description("Hello")]
Bar,
[Description("World")]
Baz
}
var value = Foo.Bar;
var description = value.GetDescription(); // Hello
根据您的需要,如果反射对您来说太慢,您可以缓存描述,只需修改 GetDescription
方法。
编辑:考虑评论中的附加信息。
因为看起来您需要更可扩展的东西,您可以使用自定义属性:
[AttributeUsage(AttributeTargets.Field, AllowMultiple = true, Inherited = false)]
public sealed class DescriptionEntryAttribute : Attribute
{
public string Key { get; private set; }
public string Value { get; private set; }
public DescriptionEntryAttribute(string key, string value)
{
Key = key;
Value = value;
}
}
哪个会让你这样做:
public enum Foo
{
[DescriptionEntry("Name", "Hello")]
[DescriptionEntry("Title", "Some title")]
Bar,
[DescriptionEntry("Name", "World")]
[DescriptionEntry("Title", "Some title")]
Baz
}
现在,要阅读这个东西,我建议你将它存储在这样的缓存中:
public static class EnumExtensions
{
private static readonly ConcurrentDictionary<Type, DescriptionCache> Caches = new ConcurrentDictionary<Type, DescriptionCache>();
public static string GetDescription(this Enum value, string key)
{
var enumType = value.GetType();
var cache = Caches.GetOrAdd(enumType, type => new DescriptionCache(type));
return cache.GetDescription(value, key);
}
public static IEnumerable<TEnum> GetValuesFromDescription<TEnum>(string key, string description)
where TEnum : struct
{
var cache = Caches.GetOrAdd(typeof(TEnum), type => new DescriptionCache(type));
return cache.GetValues(key, description).Select(value => (TEnum)(object)value);
}
private class DescriptionCache
{
private readonly ILookup<Enum, Tuple<string, string>> _items;
private readonly ILookup<Tuple<string, string>, Enum> _reverse;
public DescriptionCache(Type enumType)
{
if (!enumType.IsEnum)
throw new ArgumentException("Not an enum");
_items = (from value in Enum.GetValues(enumType).Cast<Enum>()
let field = enumType.GetField(value.ToString())
where field != null
from attribute in field.GetCustomAttributes(typeof (DescriptionEntryAttribute), false).OfType<DescriptionEntryAttribute>()
select new {value, key = attribute.Key, description = attribute.Value})
.ToLookup(i => i.value, i => Tuple.Create(i.key, i.description));
_reverse = (from grp in _items
from description in grp
select new {value = grp.Key, description})
.ToLookup(i => i.description, i => i.value);
}
public string GetDescription(Enum value, string key)
{
var tuple = _items[value].FirstOrDefault(i => i.Item1 == key);
return tuple != null ? tuple.Item2 : null;
}
public IEnumerable<Enum> GetValues(string key, string description)
{
return _reverse[Tuple.Create(key, description)];
}
}
}
这样:
Foo.Bar.GetDescription("Name")
返回 "Hello"
EnumExtensions.GetValuesFromDescription<Foo>("Title", "Some title")
返回包含 Foo.Bar
的序列和 Foo.Baz
这应该足以让您入门,现在您应该根据自己的需要对其进行调整。例如,您可以使用枚举而不是字符串作为键,这有助于避免输入错误,但我不知道这是否适合您的需要。
关于c# - 可覆盖的方法不能是静态的 : How else can I do what I'm trying to do?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25490269/
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 5 年前。 Improve
在 C# 静态方法中是否有一种方法可以引用定义该方法的类型? 在实例方法中,您可以通过以下方式确定类型: public void Foo() { Type type = this.GetTyp
WPF:静态、动态资源以及资源词典 静态资源与动态资源 我们常常会使用样式或者控件模板放在Window.Resources中,比如这样: 静态资源与动态资源使用如下: <Window
任何人都知道如何在共享/静态函数中动态加载控件?该函数本身位于 mustinherit/abstract 类中。 (这是 VB 中的 ASP.NET 项目)我想做这样的事情: VB: Publ
在我看来,静态/强类型编程语言最宝贵的一点是它有助于重构:如果/当您更改任何 API,那么编译器会告诉您该更改破坏了什么。 我可以想象用运行时/弱类型语言编写代码......但我无法想象没有编译器的帮
正如我的名字所暗示的,我是一名 .NET 开发人员,但我对 Java 的兴趣越来越大,并且我有兴趣学习更多其他语言,因为这有助于我学习更多关于编程的知识。 无论如何,我的问题是:不带参数/不使用状态的
我在java中使用WireMock来 stub POST请求。该请求返回一个存储在我本地的 json 正文文件。 stub 看起来像这样: wireMockServer.stubFor(get(url
Python 是否有类构造函数的机制,即每当首次引用类时(而不是创建该对象的实例时)调用的函数?我知道其他一些语言中也存在这种情况,但我还没有在 Python 中遇到过。 基本上,我想初始化该函数中的
Python 是否有类构造函数的机制,即每当首次引用类时(而不是创建该对象的实例时)调用的函数?我知道其他一些语言中也存在这种情况,但我还没有在 Python 中遇到过。 基本上,我想初始化该函数中的
这个问题已经有答案了: What is the difference between dynamic and static polymorphism in Java? (14 个回答) 已关闭 4 年
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Static initializer in Java 我想知道这个静态的东西(抱歉,这是我第一次遇到这个)对一个类有
如果c++应用程序是按以下方式组织的 //file1.cpp static Y sgObj = X::getInitObject(0); //declared in file scope //fil
我有一个抽象类(AvergedDataRecord),我需要进一步抽象(DataRecord),这样我就可以将它扩展到原始类和一个新的具体类(SummedDataRecord),并且我在获取某些方法时
我正在尝试制作一个字符串枚举。这是我到目前为止所得到的, private class TypedEnum : IEnumerable { public IEnumerator GetEnume
我选修了一门名为“安全代码”的类(class),在下一个作业中,我们应该对一些 C 文件和 JavaEE Web 项目进行静态/动态分析。 我检查了“源监视器”并在 C 文件上运行它,但是(除非我不知
我有两个类,一个是登录类,一个是用户类。在 loggedIn 类中,我想显示我在用户登录时所做的共享首选项。 loginPrefs = getSharedPreferences("loginprefe
我在同一个 Activity 中有两个静态 fragment ,在“fragmentA”中我有一个自定义列表,当一个项目被点击时必须在“fragmentB”中出现一个细节,细节只在我改变屏幕方向时出现
在 Java 中是未修改方法变量,缺少final,每次都重新初始化限定符 静态方法 实例方法 如果 1. 或 2.(或两者)的答案是 final 限定符允许 Java 执行优化并存储方法变量只有一次?
我有两个类相互交互。第一个是中心的,如下: public class Datenbank { double winkelPanel = 0; double groessePanel = 0; doub
我有一个 mysql 数据库,它连接基于 Web 的 php 应用程序和 FoxPro 应用程序(是的,foxpro)。在之前的“开发人员”被解雇后开始处理这个问题。 无论如何,我熟悉 AES_Enc
我是一名优秀的程序员,十分优秀!