热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c#–可覆盖的方法不能是静态的:我怎样才能做我想做的事情?

我有一系列静态类,用于获取枚举值的字符串.他们都看起来像这样:publicstaticclassMyEnumToString{privatestaticDictionary

我有一系列静态类,用于获取枚举值的字符串.他们都看起来像这样:

public static class MyEnumToString
{
private static Dictionary map
= new Dictionary();
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";
}
}

我有这样的多个类,它们使用的Enum类型和字符串值不同.显然,我应该结合使用这些类来减少重复的代码.

我尝试做的是创建通用基类,以便它可以处理任何类型,然后为继承的类实现PopulateMap.如果有可能,它看起来像这样:

public static class TypeToString
{
public static Dictionary map
= new Dictionary();
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
{
public static void PopulateMap()
{
map[MyEnum.enum1] = "string for enum 1";
map[MyEnum.enum2] = "string for enum 2";
}
}

我不得不将字典和方法PopulateMap公开,因为显然泛型类不能有protected或protected-internal成员.必须公开这个并不理想,但不是一个交易破坏者.

我所依赖的是“可覆盖的方法不能是静态的”,所以我的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()
.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 Caches = new ConcurrentDictionary();
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 GetValuesFromDescription(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> _items;
private readonly ILookup, Enum> _reverse;
public DescriptionCache(Type enumType)
{
if (!enumType.IsEnum)
throw new ArgumentException("Not an enum");
_items = (from value in Enum.GetValues(enumType).Cast()
let field = enumType.GetField(value.ToString())
where field != null
from attribute in field.GetCustomAttributes(typeof (DescriptionEntryAttribute), false).OfType()
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 GetValues(string key, string description)
{
return _reverse[Tuple.Create(key, description)];
}
}
}

这条路:

> Foo.Bar.GetDescription(“Name”)返回“Hello”
> EnumExtensions.GetValuesFromDescription(“Title”,“Some title”)返回包含Foo.Bar和Foo.Baz的序列

这应该足以让你开始,现在你应该调整它以满足你的需求.例如,您可以使用枚举而不是字符串作为键,这有助于避免键入错误,但我不知道这是否适合您的需要.


推荐阅读
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Android 渐变圆环加载控件实现
    本文介绍了如何在 Android 中创建一个自定义的渐变圆环加载控件,该控件已在多个知名应用中使用。我们将详细探讨其工作原理和实现方法。 ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • 本文介绍如何在 Android 中通过代码模拟用户的点击和滑动操作,包括参数说明、事件生成及处理逻辑。详细解析了视图(View)对象、坐标偏移量以及不同类型的滑动方式。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文介绍如何使用Objective-C结合dispatch库进行并发编程,以提高素数计数任务的效率。通过对比纯C代码与引入并发机制后的代码,展示dispatch库的强大功能。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 主要用了2个类来实现的,话不多说,直接看运行结果,然后在奉上源代码1.Index.javaimportjava.awt.Color;im ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 在前两篇文章中,我们探讨了 ControllerDescriptor 和 ActionDescriptor 这两个描述对象,分别对应控制器和操作方法。本文将基于 MVC3 源码进一步分析 ParameterDescriptor,即用于描述 Action 方法参数的对象,并详细介绍其工作原理。 ... [详细]
  • MQTT技术周报:硬件连接与协议解析
    本周开发笔记重点介绍了在新项目中使用MQTT协议进行硬件连接的技术细节,涵盖其特性、原理及实现步骤。 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
author-avatar
士贤俊宪秀珍
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有