简体   繁体   English

自定义属性并在 C# 中访问它们

[英]Custom Attributes and Accessing Them In C#

I am working on an application that stores data in the ConfigurationManager.AppSettings file, and I am wanting to implement it in a different way than how I do right now.我正在开发一个将数据存储在 ConfigurationManager.AppSettings 文件中的应用程序,并且我希望以不同于我现在的方式来实现它。 Currently, I have an interface (see below) that each class with saveable traits needs to implement, then call the static save methods from my Config class (example below).目前,我有一个接口(见下文),每个具有可保存特征的 class 都需要实现,然后从我的配置 class 调用 static 保存方法(示例如下)。 I don't like the coupling between my Config class and the class with the saveable data, so my ideal would be to have an attribute that indicates a property should be saved.我不喜欢我的配置 class 和 class 与可保存数据之间的耦合,所以我的理想是有一个属性来指示应该保存一个属性。 Then, instead of calling the SaveData or LoadData functions in my manager class, I would call a function that sets/saves all the attributed properties.然后,我不会在我的经理 class 中调用 SaveData 或 LoadData 函数,而是调用设置/保存所有属性属性的 function。 This seems similar to how [Serializeable] works in default C#, so I imagine it's possible somehow.这似乎类似于 [Serializeable] 在默认 C# 中的工作方式,所以我想这是可能的。 However, most of my searches have been fruitless.然而,我的大部分搜索都没有结果。 Any ideas on how to implement something like this?关于如何实现这样的事情的任何想法?

Interface界面

见接口

Example例子

例子

Reflection is what you're looking for. 反射是您正在寻找的。

Reflection provides objects (of type Type) that describe assemblies, modules, and types.反射提供了描述程序集、模块和类型的对象(Type 类型)。 You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties.您可以使用反射动态创建类型的实例,将类型绑定到现有 object,或从现有 object 获取类型并调用其方法或访问其字段和属性。 If you are using attributes in your code, reflection enables you to access them.如果您在代码中使用属性,反射使您能够访问它们。

Assuming that you're only interested in properties, you can use typeof or GetType to get an instance of System.Type .假设您只对属性感兴趣,您可以使用typeofGetType来获取System.Type的实例。 You can then call GetProperties to get an IEnumerable<PropertyInfo> .然后,您可以调用GetProperties来获取IEnumerable<PropertyInfo> PropertyInfo has an Attributes property that you can use to retrieve the attributes for that property. PropertyInfo有一个Attributes属性,您可以使用它来检索该属性的属性。 You can also use an instance of PropertyInfo to retrieve the value of the property.您还可以使用PropertyInfo的实例来检索属性的值。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

[AttributeUsage(AttributeTargets.Property)]
public class MyAttribute : Attribute
{

}

public class Foo
{
   [My]
   public string Bar { get; set; }

   public string Baz { get; set; }

   [My]
   public string Id { get; set; }
}

public static class Utilities
{
   public static IEnumerable<PropertyInfo> GetPropertiesWithMyAttribute(object obj)
   {
      return obj.GetType()
         .GetProperties(BindingFlags.Instance | BindingFlags.Public)
         .Where(pi => pi.CustomAttributes.Any(ca => ca.AttributeType == typeof(MyAttribute)));
   }
}

class Program
{
   static void Main(string[] args)
   {
      var foo = new Foo()
      {
         Bar = "Bar_Value",
         Baz = "Baz_Value",
         Id = "Id_Value"
      };

      foreach (var pi in Utilities.GetPropertiesWithMyAttribute(foo))
      {
         Console.WriteLine($"{pi.Name}: {pi.GetMethod.Invoke(foo, null).ToString()}");
      }
      foreach (var pi in Utilities.GetPropertiesWithMyAttribute(foo))
      {
         pi.SetMethod.Invoke(foo, new object[] { $"{pi.Name}_Value_Reflection" });
      }
      Console.WriteLine(foo.Bar);
      Console.WriteLine(foo.Baz);
      Console.WriteLine(foo.Id);
      Console.ReadKey();
   }
}

Of course, this example only string properties.当然,这个例子只是string属性。 You're going to have to figure out some way to deal with properties that aren't strings;您将不得不想出一些方法来处理不是字符串的属性; for example you haven an ObservableCollection in your example.例如,您的示例中有一个ObservableCollection

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM