简体   繁体   English

从BaseClass(C#.NET 4.0)中的SubClass获取自定义属性

[英]Get custom attribute from SubClass in BaseClass (C# .NET 4.0)

Ok, edited the code for clarification: 好的,编辑代码以进行澄清:

Question: How can I access the attribute [MyAttr("...")] in TestClassOne/Two from BaseClass.TheAttribute ...? 问题:如何从BaseClass.TheAttribute TestClassOne/Two [MyAttr("...")]属性?

All classes except TestClassOne/Two will be compiled in to my "core" and delivered as a dev-platform to a customer. 除TestClassOne / Two以外的所有类都将编译到我的“核心”中,并作为开发平台交付给客户。 The TestClassOne/Two is developed by the customer, so there can be no knowledge of the TestClassOne/Two in the "core". TestClassOne / Two是由客户开发的,因此在“核心”中可能没有TestClassOne / Two的知识。

Code below is compiled into "core" and delivered to customer as dll. 下面的代码被编译为“核心”,并以dll形式交付给客户。

[TestMethod()]
public void AttrTest()
{
    var one = new TestClassOne();
    var attrOne = one.MyTestProperty.TheAttribute;

    var two = new TestClassTwo();
    var attrTwo = two.MyTestProperty.TheAttribute;
}

public class MyAttr : Attribute
{
    private string _test;
    public MyAttr(string test)
    {
        this._test = test;
    }
}

public class BaseClass
{
    public string TheAttribute
    {
        get { 
            // Here I would like to get the "[MyAttr("...")]" from the classes in the bottom

            return null;
        }
    }
}

public class SubClass : BaseClass
{

}

Code below is developed by customer (using my dll's) 以下代码由客户开发(使用我的dll)

public class TestClassOne
{
    [MyAttr("Attribute one")]
    public SubClass MyTestProperty = new SubClass();
}

public class TestClassTwo
{
    [MyAttr("Attribute two")]
    public SubClass MyTestProperty = new SubClass();
}

Edit 3: 编辑3:

You can walk the call stack, looking for a relevant attribute in a relevant member in a relevant class. 您可以遍历调用堆栈,在相关类的相关成员中查找相关属性。 Try this: 尝试这个:

public class MyAttr : Attribute
{
    private string _test;
    public MyAttr(string test)
    {
        this._test = test;
    }

    public string getAttr()
    {
        return _test;
    }
}


public class BaseClass
{
    private string theString;

    public BaseClass()
    {
        StackTrace callStack = new StackTrace();

        for ( int i = 0; i < callStack.FrameCount; i++ )
        {
            Type t = callStack.GetFrame(i).GetMethod().DeclaringType;
            foreach ( MemberInfo m in t.GetMembers().Where(x => typeof(BaseClass).IsAssignableFrom(x.Type)) )
            {
                foreach ( var z in  m.GetCustomAttributes(typeof(MyAttr)) )
                {
                    MyAttr theAttr = z as MyAttr;
                    if ( z!= null )
                    {
                        theString = z.getAttr();
                        return;
                    }
                }
            }
        }
    }

    public string Test
    {
        get { 
            return theString;
        }
    }
}

This requires that your customer always initializes the SubClass member inside the class that declares it. 这要求您的客户始终在声明它的类中初始化SubClass成员。 If they start deriving TestClassOne or have it and TestClassTwo derive from a common class that initializes the member, this code will break. 如果他们开始派生TestClassOne或让它和TestClassTwo从初始化成员的通用类派生,则此代码将中断。

With clever use of reflection, you can expand the above code to cover more use cases, but that's beyond the scope of this question. 通过巧妙地使用反射,您可以扩展上面的代码以涵盖更多的用例,但这超出了此问题的范围。

Edit 2: 编辑2:

No. I'm sorry, but what you're trying to do isn't possible. 不。很抱歉,但是您要执行的操作无法实现。 There's no "normal" way for an instance of SubClass to know if it's being declared in a member field of some other object, or in an element in an array or in a temporary variable in the stack, or whatever. SubClass实例没有“正常”的方式来知道它是在其他对象的成员字段中,在数组中的元素中还是在堆栈中的临时变量中或在堆栈中的临时变量中声明的。 As such, there's no way for that instance to access the attributes of the member field that's declaring it. 因此,该实例无法访问声明它的成员字段的属性。

(I suppose you might want to try to access the garbage collector to find out where in memory the this object lives, but that's probably way beyond the scope of this problem, and in any case, not something I know how to do.) (我想您可能想尝试访问垃圾收集器,以找出this对象在内存中的位置,但这可能超出了此问题的范围,无论如何,我都不知道该怎么做。)

I suspect your problem lies elsewhere entirely. 我怀疑您的问题完全在其他地方。 Maybe you need to require your customer to make TestClassOne and TestClassTwo derive from a common abstract class. 也许您需要要求客户使TestClassOneTestClassTwo派生自一个常见的抽象类。 Maybe they need to derive from BaseClass themselves. 也许他们需要自己从BaseClass派生。 Maybe you need to add parameters to the constructor. 也许您需要向构造函数添加参数。 Maybe you need to provide a different interface altogether. 也许您需要完全提供其他接口。 We can't know unless you provide more information on your specific business requirements. 除非您提供有关特定业务需求的更多信息,否则我们不会知道。

Edit: 编辑:

To access the attributes declared on the MyTest member, try something along these lines: 要访问在MyTest成员上声明的属性,请尝试以下方式:

public class BaseClass
{
    public string Test
    {
        get { 
            var attr = typeof(Test).GetMembers().Where(x => x.Type == this.GetType()).First().GetCustomAttributes(true);
            return null;
        }
    }
}

This will search class Test for a member with the same type as this and look for attributes on that member. 这将搜索类Test具有相同类型的成员this并查找部件属性。

(I don't have my Visual Studio here, to check the exact Where syntax, but it should be pretty close to that...) (我这里没有我的Visual Studio,以检查确切的Where语法,但它应该与之很接近...)

Original Answer: 原始答案:

Your attribute is declared on the MyTest member of class Test . 您的属性在Test类的MyTest成员上声明。 But, you're doing GetCustomAttributes on class SubClass itself. 但是,您正在对类SubClass本身进行GetCustomAttributes

Try this: 尝试这个:

[MyAttr("apa")]
public class SubClass : BaseClass
{

}

public class Test
{
    public SubClass MyTest = new SubClass();
}

Should get you what you want. 应该给你你想要的。

You can get directly from type Test : 您可以直接从Test类型获取:

var result = typeof (Test)
               .GetField("MyTest", BindingFlags.Public | BindingFlags.Instance)
               .GetCustomAttribute<MyAttr>();

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

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