如何使用属性添加静态构造函数行为
本文关键字:构造函数 静态 添加 何使用 属性 | 更新日期: 2023-09-27 17:56:31
我想使用具有相同行为的类的属性添加静态构造函数行为(在我的例子中是静态字段占位符替换)。
实际上,我显式调用静态构造函数,使用一个实用程序类执行带有反射的静态 stuf:
public class Util
{
public static void perform(System.Type container)
{
// do the static stuff (basically initializing readonly fields
}
}
public class AClass
{
static AClass()
{
Util.perform(typeof(AClass));
}
private static readonly string A = "eza";
private static readonly string B = "$A.dat";
}
我想以这种方式使用实用程序类:
[StaticVerbatimPlaceholderSubstitution]
public class A
{
private static readonly string A = "eza";
private static readonly string B = "$A.dat";
}
实际上我知道如何扩展属性类。困扰我的是如何在正确的时间打电话。实际上在代码期间(在主或控制器中)使用它听起来不像静态构造函数(在类的任何实例化之前)。
如果有人可以帮助我并告诉将属性的消费代码放在哪里,我会非常高兴。
此外,如果可以具有相同的实用程序代码(也是消耗部分),则包含引用足以提供行为,而无需对客户端代码进行代码调整。
谢谢
使用代码进行编辑以进行理解:
using System;
using System.Reflection;
using System.Collections;
using System.Text.RegularExpressions;
namespace Utils
{
/// <summary>
/// Classe utilitaire pour initialiser les champs de chaines de caractères statiques en lecture seuls.
/// Cette classe, permet de faire de la substitution de chaine de caractère en utilisant les expressions :
/// ${...} qui sont remplacer sur place (verbatim) dans la chaine appelante.
/// Si des autoréférences sont présentes, le code lève une exception TypeInitializationException lors l'appel à la classe.
/// </summary>
public class VerbatimPlaceHolder
{
public static void ReplaceAll(System.Type container)
{
Hashtable computed = new Hashtable();
Hashtable visited = new Hashtable();
FieldInfo[] fields = container.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo field in fields)
{
Replace(container, field, visited, computed);
}
}
private static void Replace(System.Type container, FieldInfo field, Hashtable visited, Hashtable computed)
{
if (computed.ContainsKey(field.Name)) return;
if (visited.ContainsKey(field.Name))
{
string names = "";
foreach (string name in visited.Keys) names += (names.Length > 0 ? ", " : "") + name;
throw new Exception("[ERREUR FATALE] autoréférence dans la définition des champs statiques {" + names + "} de la classe " + container.Name);
}
if (field != null && field.IsStatic && field.IsInitOnly && field.FieldType == typeof(string))
{
visited.Add(field.Name, field);
string result = (string) field.GetValue(null);
Regex placeHolderPattern = new Regex(@"'$'{([_a-zA-Z0-9]*)'}");
foreach (Match sub in placeHolderPattern.Matches(result))
{
FieldInfo node = container.GetField(sub.Groups[1].Value, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (node == null)
{
throw new Exception("[ERREUR FATALE] le champ statique " + sub.Value + " n'est pas défini pour " + container.Name + "." + field.Name);
}
Replace(container, node, visited, computed);
result = result.Replace(sub.Value, (string) node.GetValue(null));
}
//removing space and line breaks
Regex blanks = new Regex(@"['s'r'n]+");
result = blanks.Replace(result, " ");
field.SetValue(null, result);
computed.Add(field.Name, field);
visited.Remove(field.Name);
}
}
}
}
好的,我想我必须寻找带有 IL 注入的模块初始值设定项(根据单声道塞西尔或 Postsharp)。
在Web上下文中,存在允许这种行为的IAssemblyPosProcessor,但这只是Web上下文,我也想使库在批处理模式下工作。