草庐IT

c# - 任何人都知道一种快速获取枚举值自定义属性的方法吗?

coder 2024-05-19 原文

这可能最好用一个例子来说明。我有一个带有属性的枚举:

public enum MyEnum {

    [CustomInfo("This is a custom attrib")]
    None = 0,

    [CustomInfo("This is another attrib")]
    ValueA,

    [CustomInfo("This has an extra flag", AllowSomething = true)]
    ValueB,
}

我想从实例中获取这些属性:

public CustomInfoAttribute GetInfo( MyEnum enumInput ) {

    Type typeOfEnum = enumInput.GetType(); //this will be typeof( MyEnum )

    //here is the problem, GetField takes a string
    // the .ToString() on enums is very slow
    FieldInfo fi = typeOfEnum.GetField( enumInput.ToString() );

    //get the attribute from the field
    return fi.GetCustomAttributes( typeof( CustomInfoAttribute  ), false ).
        FirstOrDefault()        //Linq method to get first or null
        as CustomInfoAttribute; //use as operator to convert
}

因为这是使用反射,所以我预计会有些慢,但是当我已经有了它的实例时,将枚举值转换为字符串(反射(reflect)名称)似乎很麻烦。

有没有人有更好的方法?

最佳答案

这可能是最简单的方法。

一种更快的方法是使用动态方法和 ILGenerator 静态发出 IL 代码。虽然我只将它用于 GetPropertyInfo,但不明白为什么您也不能发出 CustomAttributeInfo。

例如从属性发出 getter 的代码

public delegate object FastPropertyGetHandler(object target);    

private static void EmitBoxIfNeeded(ILGenerator ilGenerator, System.Type type)
{
    if (type.IsValueType)
    {
        ilGenerator.Emit(OpCodes.Box, type);
    }
}

public static FastPropertyGetHandler GetPropertyGetter(PropertyInfo propInfo)
{
    // generates a dynamic method to generate a FastPropertyGetHandler delegate
    DynamicMethod dynamicMethod =
        new DynamicMethod(
            string.Empty, 
            typeof (object), 
            new Type[] { typeof (object) },
            propInfo.DeclaringType.Module);

    ILGenerator ilGenerator = dynamicMethod.GetILGenerator();
    // loads the object into the stack
    ilGenerator.Emit(OpCodes.Ldarg_0);
    // calls the getter
    ilGenerator.EmitCall(OpCodes.Callvirt, propInfo.GetGetMethod(), null);
    // creates code for handling the return value
    EmitBoxIfNeeded(ilGenerator, propInfo.PropertyType);
    // returns the value to the caller
    ilGenerator.Emit(OpCodes.Ret);
    // converts the DynamicMethod to a FastPropertyGetHandler delegate
    // to get the property
    FastPropertyGetHandler getter =
        (FastPropertyGetHandler) 
        dynamicMethod.CreateDelegate(typeof(FastPropertyGetHandler));


    return getter;
}

关于c# - 任何人都知道一种快速获取枚举值自定义属性的方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17772/

有关c# - 任何人都知道一种快速获取枚举值自定义属性的方法吗?的更多相关文章

  1. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  2. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  5. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  6. ruby-on-rails - link_to 不显示任何 rails - 2

    我试图在索引页中创建一个超链接,但它没有显示,也没有给出任何错误。这是我的index.html.erb代码。ListingarticlesTitleTextssss我检查了我的路线,我认为它们也没有问题。PrefixVerbURIPatternController#Actionwelcome_indexGET/welcome/index(.:format)welcome#indexarticlesGET/articles(.:format)articles#indexPOST/articles(.:format)articles#createnew_articleGET/article

  7. ruby - Nokogiri 剥离所有属性 - 2

    我有这个html标记:我想得到这个:我如何使用Nokogiri做到这一点? 最佳答案 require'nokogiri'doc=Nokogiri::HTML('')您可以通过xpath删除所有属性:doc.xpath('//@*').remove或者,如果您需要做一些更复杂的事情,有时使用以下方法遍历所有元素会更容易:doc.traversedo|node|node.keys.eachdo|attribute|node.deleteattributeendend 关于ruby-Nokog

  8. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  9. ruby-on-rails - RSpec:避免使用允许接收的任何实例 - 2

    我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_

  10. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

随机推荐