首页 > 解决方案 > 在 C# 属性中构建字典

问题描述

我正在寻找在属性中构建字典。

我知道AllowMultiple在 C# 中使用属性,但这会导致该属性被调用并且(在我的情况下,因为它是一个过滤器)触发了两次。

本质上,我想要这种行为:

[MyAttribute("someKey", "value1", "value2", "value3")]
[MyAttribute("someOtherKey", "value1", "value2", "value3")]

导致一个Dictionary<string, HashSet<string>>里面MyAttribute。但是,由于显而易见的原因,这不起作用,因为每一行都实例化了一个全新的MyAttribute.

有什么好办法解决这个问题吗?属性是否支持这一点,还是我需要想出一些厚颜无耻的方式将参数传递到一个单一的属性声明中?

编辑:我应该注意......这是用于授权过滤器。它应该可以为多个潜在值授权多个环境(键)。但是,我不能使用该属性的多个实例,因为这样过滤器将被触发多次。

标签: c#attributes

解决方案


这是将复杂信息插入属性的一种方法,使用与 System.ComponentModel.TypeConverterAttribute 相同的模式:通过将复杂性隐藏在类型中,并使用 typeof(MyType) 作为赋予属性的编译时间常数。

public class MyAttributeAttribute : AuthorizeAttribute
{
    public MyAttributeAttribute(Type t) : base()
    {
        if (!typeof(MyAbstractDictionary).IsAssignableFrom(t))
        {
            // ruh roh; wrong type, so bail
            return;
        }
        // could also confirm parameterless constructor exists before using Activator.CreateInstance(Type)

        Dictionary<string, HashSet<string>> dictionary = ((MyAbstractDictionary)Activator.CreateInstance(t)).GetDictionary();
        this.Roles = "Fill Roles by using values from dictionary";
        // fill any other properties from the dictionary
    }
}

public abstract class MyAbstractDictionary
{
    public abstract Dictionary<string, HashSet<string>> GetDictionary();
}

public class MyDictionary : MyAbstractDictionary
{
    public MyDictionary() { } // gotta have a parameterless constructor; add it here in case we actually make another constructor
    public override Dictionary<string, HashSet<string>> GetDictionary()
    {
        Dictionary<string, HashSet<string>> dict = new Dictionary<string, HashSet<string>>();
        // build dictionary however you like
        return dict;
    }
}

使用抽象类,因此您可以创建返回不同字典的不同类型。

和用法:

[MyAttribute(typeof(MyDictionary))]
public class ClassToAttribute { }

然后,您可以继续MyDictionary2使用不同的字典创建类,并将其用作 typeof() 来归因于其他事物。您现在还可以使用运行时信息 (!) 来构建字典,而不仅仅是硬编码值。


推荐阅读