C#自定义属性代码->;查看与之关联的字段

C#自定义属性代码->;查看与之关联的字段,c#,reflection,custom-attributes,C#,Reflection,Custom Attributes,我有一个C#类,在我的自定义DB ORM工具中使用,称为DbFieldAttribute 我把它放在我的场地上,就像这样: [DbField("User_Id")] public int UserId{ get; set; } 挑战:从我的属性构造函数代码中,获取与属性关联的字段的FieldInfo。在上面的例子中,它会给我UserId的FieldInfo 任何帮助都会很好。谢谢。不幸的是,据我所知,没有办法实现你的要求 但是,如果没有必要在构造函数中获取PropertyInfo或FieldI

我有一个C#类,在我的自定义DB ORM工具中使用,称为DbFieldAttribute

我把它放在我的场地上,就像这样:

[DbField("User_Id")]
public int UserId{ get; set; }
挑战:从我的属性构造函数代码中,获取与属性关联的字段的FieldInfo。在上面的例子中,它会给我UserId的FieldInfo


任何帮助都会很好。谢谢。

不幸的是,据我所知,没有办法实现你的要求

但是,如果没有必要在构造函数中获取PropertyInfo或FieldInfo对象,但是您会对将其传递给方法感到满意,那么有一个可能的解决方案

首先,需要用以下方式定义DbField类

class DbField : Attribute
{
    public DbField(string source) { }

    public void GetInstance(PropertyInfo source)
    {
        Console.WriteLine(source.Name);
    }
}
然后需要定义以下类,该类将获取所有(在本例中)用DbField属性标记的属性,并将它们传递给GetInstance(PropertyInfo)方法

现在,您的目标类(其属性由DbField属性修饰)只需要从该类派生,这样您就不会被构造函数内部的调用所困扰

class DecoratedClass : AbstractDecoratedClass
{
    [DbField("User_Id")]
    public int UserId { get; set; }

    [DbField("User_Id2")]
    public int UserId2 { get; set; } 
}
现在只剩下测试解决方案,如图所示

class Program
{
    static void Main()
    {
        new DecoratedClass();

        Console.Read();
    }
}

正如@Mario所指出的,这个解决方案无法直接解决,但我最终选择了这个解决方案

关键是要知道属性本身无法知道这些信息,但在调用它时,可以合理地预期FieldInfo或PropertyInfo也可用

我最初的问题是,我的ORM代码查看属性以确定字段/属性是否与数据库字段相关。然后,我遇到了一些实例,其中类中的Prop/字段名与数据库不匹配,这是因为它对代码/Db更具逻辑性。在这些情况下,我需要传入一个要使用的字段名,而不是实际的字段名。我希望该属性可以做更多的工作,或者至少有助于使它在将来使用它的代码中更加明显

(我去掉了与此解决方案无关的xml注释和额外代码)


现在,当我的ORM代码需要字段名时,它必须传入与该字段相关的字段或属性信息。这意味着所需的内容现在在属性使用中是固有的,而不需要在外部代码中派生。

这是一个属性,而不是字段,因此使用反射获取所有属性,并检查每个
PropertyInfo
是否具有所需的自定义属性。属性不会神奇地触发。。一定有什么东西要把他们炒了。当您检查属性是否存在时,可以通过属性传递对
属性info
的引用。谢谢。该属性同时适用于属性和字段,我无意中显示了其中一种属性类型。@Jeppe:使用您所说的反射获取所有属性,但我如何确定它附加到的对象,然后,如何知道我是否正在查看write属性?这是最初问题的核心我不确定我是否正确理解了您,但我想您可以做一些类似于
typeof(您拥有的类).GetProperties.Where(pi=>pi.GetCustomAttributes(typeof(DbFieldAttribute),false).Length!=0)
或类似的事情。这只是给你该类的所有具有该属性的公共属性。这似乎比它需要的要复杂一些。使这个解决方案起作用的关键(帮助我解决这个问题的同一个关键)是外部的东西需要传入类或prop/fieldinfo到属性。我所做的只是将FieldName的属性更改为一对重载方法,期望将propertyinfo或fieldinfo传递给它。然后,如果从未设置字段名,它将从信息中返回名称。这两种方法都解决了问题,只是不像我希望.NET处理的那样优雅。在大多数其他情况下,您可以使用堆栈跟踪信息查找父级,但在这种情况下,堆栈跟踪解析回ORM,而不是类字段/属性。-谢谢。我希望我能将成功的答案应用于你发布的解决方案和我的解决方案,因为你提供了一个有效的解决方案。我选择了我的,因为我觉得这是一个更简单的实现/理解的选项。谢谢
class DecoratedClass : AbstractDecoratedClass
{
    [DbField("User_Id")]
    public int UserId { get; set; }

    [DbField("User_Id2")]
    public int UserId2 { get; set; } 
}
class Program
{
    static void Main()
    {
        new DecoratedClass();

        Console.Read();
    }
}
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class DbFieldAttribute : Attribute
{
    private string fieldName = "";

    public DbFieldAttribute() { }

    public DbFieldAttribute(string fieldName)
    {
        this.fieldName = fieldName;
    }

    public string FieldName(PropertyInfo pi)
    {
        if (this.fieldName != "") return this.fieldName;
        else return pi.Name;
    }

    public string FieldName(FieldInfo fi)
    {
        if (this.fieldName != "") return this.fieldName;
        else return fi.Name;
    }