获取自定义在BaseClass的从属性SubClass中(C#.NET 4.0) [英] Get custom attribute from SubClass in BaseClass (C# .NET 4.0)

查看:454
本文介绍了获取自定义在BaseClass的从属性SubClass中(C#.NET 4.0)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,编辑澄清code:

问:我如何访问属性 [MyAttr(...)] TestClassOne /双 BaseClass.TheAttribute ...

除了TestClassOne /双所有课程将被编译到我的核心,并作为开发平台向客户交付。
该TestClassOne /二是由客户开发的,所以可以在核心是没有TestClassOne /两方面的知识。

code以下被编译成核心并交付给客户的DLL。

  [TestMethod的()]
公共无效AttrTest()
{
    VAR 1 =新TestClassOne();
    VAR attrOne = one.MyTestProperty.TheAttribute;    VAR 2 =新TestClassTwo();
    VAR attrTwo = two.MyTestProperty.TheAttribute;
}公共类MyAttr:属性
{
    私人字符串_test;
    公共MyAttr(字符串测试)
    {
        this._test =测试;
    }
}公共类BaseClass的
{
    公共字符串TheAttribute
    {
        获得{
            //这里我想获得[MyAttr(...)]从底部的类            返回null;
        }
    }
}公共类亚纲:BaseClass的
{}

code以下是由客户开发(使用我的动态链接库)

 公共类TestClassOne
{
    [MyAttr(属性1)]
    公共SubClass中MyTestProperty =新的子类();
}公共类TestClassTwo
{
    [MyAttr(属性的两个)]
    公共SubClass中MyTestProperty =新的子类();
}


解决方案

修改3:

您可以步行调用堆栈,寻找相关类相关成员的相关属性。试试这个:

 公共类MyAttr:属性
{
    私人字符串_test;
    公共MyAttr(字符串测试)
    {
        this._test =测试;
    }    公共字符串GETATTR()
    {
        返回_test;
    }
}
公共类BaseClass的
{
    私人字符串theString;    公众的BaseClass()
    {
        堆栈跟踪调用堆栈=新的堆栈跟踪();        的for(int i = 0; I< callStack.FrameCount;我++)
        {
            类型t = callStack.GetFrame(I).GetMethod()DeclaringType。
            的foreach(在t.GetMembers的MemberInfo米()其中(x =方式>的typeof(BaseClass的).IsAssignableFrom(x.Type)))
            {
                的foreach(在m.GetCustomAttributes变种Z(typeof运算(MyAttr)))
                {
                    MyAttr theAttr = Z为MyAttr;
                    如果(Z!= NULL)
                    {
                        theString = z.getAttr();
                        返回;
                    }
                }
            }
        }
    }    公共字符串测试
    {
        获得{
            返回theString;
        }
    }
}

这要求你的客户总是初始化子类成员声明它的类里面。如果他们开始得出 TestClassOne 或有它和 TestClassTwo 从通用类初始化成员,这$ C $派生按c打破。

通过巧妙地利用反射,可以展开上述code覆盖更多的用例,但这超出了这个问题的范围。

编辑2:

没有。我很抱歉,但是你想做什么是不可能的。还有为子类的实例没有正常的方式来知道它是否在其他对象的成员领域正在申报,或在一个数组或一个临时的元素变量在堆栈中,或什么的。因此,有没有办法为实例来访问的宣告它的成员字段的属性。

(我猜你可能要尝试访问的垃圾收集器,找出在内存中的这个对象的生活,但是这可能远远超出这个问题的范围,在任何情况下,不是我知道怎么做的。)

我怀疑你的问题出在其它地方完全。也许你需要需要您的客户做出 TestClassOne TestClassTwo 从一个共同的抽象类派生。也许他们需要从的BaseClass 自己去获得。也许你需要的参数添加到构造。也许你需要提供完全不同的接口。我们无法知道,除非你提供您的具体业务要求的更多信息。

编辑:

要访问MyTest的部件上声明的属性,尽量沿着这些路线的内容:

 公共类BaseClass的
{
    公共字符串测试
    {
        获得{
            VAR ATTR = typeof运算(测试).GetMembers(),其中(X => x.Type == this.GetType())。首先()GetCustomAttributes(真)。
            返回null;
        }
    }
}

这将搜索类测试对于同一类型的成员为这个并查找成员属性

(我没有我的Visual Studio在这里,要检查的确切其中,语法,但它应该是pretty接近...)

原来的答复:

您属性声明的类的 MyTest的成员测试。但是,你正在做的 GetCustomAttributes 阶级 SubClass中本身。

试试这个:

  [MyAttr(APA)]
公共类亚纲:BaseClass的
{}公共类测试
{
    公共SubClass中MyTest的=新的子类();
}

应该给你你想要的东西。

Ok, edited the code for clarification:

Question: How can I access the attribute [MyAttr("...")] in TestClassOne/Two from BaseClass.TheAttribute...?

All classes except TestClassOne/Two will be compiled in to my "core" and delivered as a dev-platform to a customer. The TestClassOne/Two is developed by the customer, so there can be no knowledge of the TestClassOne/Two in the "core".

Code below is compiled into "core" and delivered to customer as 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)

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

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

解决方案

Edit 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. If they start deriving TestClassOne or have it and TestClassTwo derive from a common class that initializes the member, this code will break.

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:

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. 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.)

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. Maybe they need to derive from BaseClass themselves. 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:

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.

(I don't have my Visual Studio here, to check the exact Where syntax, but it should be pretty close to that...)

Original Answer:

Your attribute is declared on the MyTest member of class Test. But, you're doing GetCustomAttributes on class SubClass itself.

Try this:

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

}

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

Should get you what you want.

这篇关于获取自定义在BaseClass的从属性SubClass中(C#.NET 4.0)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆