如何接受数据的“字典”作为自定义.NET属性参数?

时间:2021-08-07 07:27:41

I recently discovered that a .NET attribute can only contain primitive types, strings, enums, objects, and single parameter arrays of these types as discussed here.

我最近发现.NET属性只能包含这些类型的基本类型,字符串,枚举,对象和单个参数数组,如此处所述。

I have the need to accept an IDictionary<string, string> through a .NET attribute, but obviously I can't use IDictionary<string, string> for the above reason. So, I am here looking for alternatives that can work within these guidelines.

我需要通过.NET属性接受IDictionary ,但显然由于上述原因我不能使用IDictionary 。所以,我在这里寻找可以在这些指导方针内工作的替代方案。 ,string> ,string>

// I want to do this, but can't because of the CLR limitation
[MyAttribute(Attributes = new Dictionary { { "visibility", "Condition1" }, { "myAttribute", "some-value" } })]

Two possible options I came up with are to use XML or JSON in the declaration (as a string on the .NET attribute), which can be easily serialized into IDictionary<string, string> for my application, but this turns the declaration into a lengthy error-prone string with no syntax checking.

我提出的两个可能的选项是在声明中使用XML或JSON(作为.NET属性上的字符串),可以很容易地为我的应用程序序列化为IDictionary ,但这会将声明转换为冗长的容易出错的字符串,没有语法检查。 ,string>

// XML
[MyAttribute(Attributes = "<items><item key='visibility' value='Condition1'/><item key='myAttribute' value='some-value'/></items>")]

// JSON
[MyAttribute(Attributes = "{ 'visibility': 'Condition1', 'myAttribute': 'some-value' }")]

What, if any, other alternatives are available that are more elegant/straightforward than this?

如果有的话,还有哪些其他替代方案比这更优雅/更直接?

3 个解决方案

#1


7  

As far as I know, you can add an attribute several times (Edit: If you set AllowMultiple to true, as Robert Levy noted). So maybe instead of using one attribute with a whole dictionary, you could use several attributes, one for each dictionary entry, each with a key and a value parameter.

据我所知,你可以多次添加一个属性(编辑:如果你将AllowMultiple设置为true,正如Robert Levy所说)。因此,可能不是将一个属性与整个字典一起使用,而是可以使用多个属性,每个字典条目一个,每个属性都有一个键和一个值参数。

[MyDictionaryEntry(Key = key1, Value = val1)]
[MyDictionaryEntry(Key = key2, Value = val2)]
[MyDictionaryEntry(Key = key3, Value = val3)]
[MyDictionaryEntry(Key = key4, Value = val4)]

#2


2  

You can define an attribute that takes 2 string parameters (key and value) and AllowMultiple=true so that multiple instances of it can be applied to a type/member

您可以定义一个属性,该属性采用2个字符串参数(键和值)和AllowMultiple = true,以便可以将多个实例应用于类型/成员

#3


2  

While it is possible for you to specify the same Attribute class multiple times, it may be more beneficial to define each property as a separate, independent attribute.

虽然您可以多次指定相同的Attribute类,但将每个属性定义为单独的独立属性可能更有用。

For example VisibilityAttribute, MyAttributeAttribute, ... etc. You could then apply each attribute individually to properties.

例如,VisibilityAttribute,MyAttributeAttribute,...等。然后,您可以将每个属性单独应用于属性。

If it seems cumbersome to reflect each manually, you could make a helper method that would reflect all the possible ones and return back a Dictionary object with each one's key/value.

如果手动反映每个似乎很麻烦,您可以创建一个反映所有可能的辅助方法,并返回一个包含每个键/值的Dictionary对象。

For example:

[Visibility("true")]
[MyAttribute("Something")]

Then you could have a helper method that does something like this:

然后你可以有一个帮助方法,做这样的事情:

static Dictionary<string, string> GetAttributeDictionary(object value)
{
  var dictionary = new Dictionary<string, string>();

  var type = value.GetType();
  var customAttributes = type.GetCustomAttributes(true);

  foreach (var attribute in customAttributes)
  {
    if (attribute is VisibilityAttribute)
    {
       var visibilityAttribute = attribute as VisibilityAttribute;
       dictionary["Visibility"] = visibilityAttribute.Visibility;
    }

    // Process other custom attributes...
  }

  return dictionary;
}

#1


7  

As far as I know, you can add an attribute several times (Edit: If you set AllowMultiple to true, as Robert Levy noted). So maybe instead of using one attribute with a whole dictionary, you could use several attributes, one for each dictionary entry, each with a key and a value parameter.

据我所知,你可以多次添加一个属性(编辑:如果你将AllowMultiple设置为true,正如Robert Levy所说)。因此,可能不是将一个属性与整个字典一起使用,而是可以使用多个属性,每个字典条目一个,每个属性都有一个键和一个值参数。

[MyDictionaryEntry(Key = key1, Value = val1)]
[MyDictionaryEntry(Key = key2, Value = val2)]
[MyDictionaryEntry(Key = key3, Value = val3)]
[MyDictionaryEntry(Key = key4, Value = val4)]

#2


2  

You can define an attribute that takes 2 string parameters (key and value) and AllowMultiple=true so that multiple instances of it can be applied to a type/member

您可以定义一个属性,该属性采用2个字符串参数(键和值)和AllowMultiple = true,以便可以将多个实例应用于类型/成员

#3


2  

While it is possible for you to specify the same Attribute class multiple times, it may be more beneficial to define each property as a separate, independent attribute.

虽然您可以多次指定相同的Attribute类,但将每个属性定义为单独的独立属性可能更有用。

For example VisibilityAttribute, MyAttributeAttribute, ... etc. You could then apply each attribute individually to properties.

例如,VisibilityAttribute,MyAttributeAttribute,...等。然后,您可以将每个属性单独应用于属性。

If it seems cumbersome to reflect each manually, you could make a helper method that would reflect all the possible ones and return back a Dictionary object with each one's key/value.

如果手动反映每个似乎很麻烦,您可以创建一个反映所有可能的辅助方法,并返回一个包含每个键/值的Dictionary对象。

For example:

[Visibility("true")]
[MyAttribute("Something")]

Then you could have a helper method that does something like this:

然后你可以有一个帮助方法,做这样的事情:

static Dictionary<string, string> GetAttributeDictionary(object value)
{
  var dictionary = new Dictionary<string, string>();

  var type = value.GetType();
  var customAttributes = type.GetCustomAttributes(true);

  foreach (var attribute in customAttributes)
  {
    if (attribute is VisibilityAttribute)
    {
       var visibilityAttribute = attribute as VisibilityAttribute;
       dictionary["Visibility"] = visibilityAttribute.Visibility;
    }

    // Process other custom attributes...
  }

  return dictionary;
}