none
Is it possible to get the instance of a class (the object) outside the class? RRS feed

  • Question

  • Hi,

    Suppose I have this code:

    public class Test
    {
     public void Start()
     {
      Number = 1;
      new Other().Begin();
     }
    
     public int Number { get; set; }
    }
    
    public class Other
    {
     public void Begin()
     {
      // I want to get the value of Test.Number, i.e. "1"
     }
    }
    

    Is it possible to get the number "1" from inside "Other.Begin"? In other words, what I want at that point is an object reference to the instance of "Test" in the current thread...

    --
    Werner

     

    Wednesday, March 9, 2011 10:08 AM

Answers

  • Hi,

    as I wrote before, I don't know what you want to reach exactly. In my first answer I also mentioned that you have to pass the object reference, if you want to acces a property of it (if the reference isn't already there).

    Do you want to have access from your class to a property of the attribute class, or vica verse, or is it somewhere else?

    If it's access from a member of the Attribute-class to property of class x (in which the attribute is used), you have to pass the object reference (of class x) to the attributes instance (after calling GetCustomAttributes()). The attribute has no information about the classes in which it is used.

    Greetings,


    Wolfgang Kluge
    gehirnwindung.de
    Friday, March 11, 2011 8:39 PM

All replies

  • Hi Werner,

    you have to use a reference to the Test-instance (this inside class Test). For this the constructor of class Other, or a property/field or the member Begin has to expect a Parameter of type Test.

    e.g.

    public void Begin(Test test){
      var n = test.Number;
    }
    

    To call it, you have to change Test.Start to

    new Other().Begin( this );
    

    You might want to check if the parameter test is not null.

    If you have more than one member in class Other with needed access to the instance of test, it might be better to use the constructor. 

    Greeting,


    Wolfgang Kluge
    gehirnwindung.de
    Wednesday, March 9, 2011 1:00 PM
  • Wolfgang is right.  You'd be violating encapsulation if your code example worked.  You have to tell your new object about the object that is creating it; otherwise, it has no idea that it or any other object exists for that matter.  Now, if Test is a common object in your system than you can look at whether or not it should be a Singleton or static.

    Dependency injection might be another option too if there is a possibility of being more than one Test object or you don't necessarily know what type to use within the Other class.  For example, instead of saying Test.Number in the Other class you might use an interface as in the following pseudo-code:

    ITest myObj = unityContainer.Resolve<ITest>();
    int myNum = myObj.Number;

    In this pseudo code your Other class either needs to know about the dependency injection container (in this example I used Unity) or it needs to have an constructor parameter that is injected when the Other object is created. Additionally, the Test object needs to be registered with the container as an instance of ITest.

    Wednesday, March 9, 2011 2:04 PM
  • Thanks both, I kinda figured this. And again I find myself asking a "simplified" version of the real problem - in the hope it would make more sense to others. My apologies - Let me try to explain what I need - and give an example where this is actually done (!). Perhaps you can comment on this too.

    I have a method attribute lets call it "NumberAttribute". So it would be like this:

    public int Number { get; set; }
    
    [NumberAttribute]
    public void Test()
    {
    }
    

    I need to access property "Number" from the attribute "NumberAttribute".

    I know this is possible - consider you write a SOAP webservice and decorate a web method with 'SoapHeader("Number")'. This would cause that the property "Number" is set to the value of the SOAP header in that method call. See example here

    So the above IS possible and it is what I need to do :). Any ideas?

    --
    Werner

    Thursday, March 10, 2011 7:05 AM
  • Hi,

    I don't understand what you want to reach...

    But to give it a try. The SoapHeaderAttribute has some properties to store some values like member name.

    Somewhere else the methods with this attribute will be searched (sorry for poor English *g*). This (and the following access to the member) is (likely) done with Reflection and Late Binding. See http://davidhayden.com/blog/dave/archive/2006/03/07/2876.aspx for an example.

    But perhaps I didn't understand your requirement exactly...

    Greetings,


    Wolfgang Kluge
    gehirnwindung.de
    Thursday, March 10, 2011 2:06 PM
  • Hi,

    I don't understand what you want to reach...

    But to give it a try. The SoapHeaderAttribute has some properties to store some values like member name.

    Somewhere else the methods with this attribute will be searched (sorry for poor English *g*). This (and the following access to the member) is (likely) done with Reflection and Late Binding. See http://davidhayden.com/blog/dave/archive/2006/03/07/2876.aspx for an example.

    But perhaps I didn't understand your requirement exactly...

    Greetings,


    Wolfgang Kluge
    gehirnwindung.de


    Hi Wolfgang,

    Well no Davids example does not cover what I'm after. In his example he's only dealing with values in the attribute itself - not values in the class where the attribute is used. To use your own words: "...and the following access to the member..." here I need to know how to access that member. Davids example does not set a value or anything inside the class.

    However the SoapHeaderAttribute takes a member name as input and uses that string name to access and set the value of that member. It is that "set" operation I want to copy.

    --
    Werner

    Friday, March 11, 2011 8:31 AM
  • Hi,

    you're right. The example doesn't fit. If you have an object, you can get/set properties via Reflection. An Example (without exception handling!):

    var t = obj.GetType();
    var textProperty = t.GetProperty( "Text", typeof( string ) );
    if( textProperty.CanRead ){
      var oldValue = (string)textProperty.GetValue( obj, null );
      // ...
    }
    if( textProperty.CanWrite ){
      textProperty.SetValue( obj, "New Value", null );
    }
    

    Greetings,


    Wolfgang Kluge
    gehirnwindung.de
    Friday, March 11, 2011 11:02 AM
  • Hi,

    you're right. The example doesn't fit. If you have an object, you can get/set properties via Reflection. An Example (without exception handling!):


    Wolfgang Kluge
    gehirnwindung.de


    Hi Wolfgang,

    Yes but as my subject of this thread indicates, my problem is getting that specific class instance. In your code you start with "obj.GetType". Where does "obj" come from? All I have is an attribute on a method. At runtime I know all about that class - as a type! I have access to all reflections and stackframes but I cannot get the actual instance that allows me to do textProperty.SetValue( obj, "New Value", null ) for example...


    --
    Werner

     

    Friday, March 11, 2011 11:18 AM
  • Hi,

    as I wrote before, I don't know what you want to reach exactly. In my first answer I also mentioned that you have to pass the object reference, if you want to acces a property of it (if the reference isn't already there).

    Do you want to have access from your class to a property of the attribute class, or vica verse, or is it somewhere else?

    If it's access from a member of the Attribute-class to property of class x (in which the attribute is used), you have to pass the object reference (of class x) to the attributes instance (after calling GetCustomAttributes()). The attribute has no information about the classes in which it is used.

    Greetings,


    Wolfgang Kluge
    gehirnwindung.de
    Friday, March 11, 2011 8:39 PM
  • Hi Werner,

    Is there any update of your question?


    Eric Yang [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, March 14, 2011 7:55 AM
  • Hi,

    as I wrote before, I don't know what you want to reach exactly. In my first answer I also mentioned that you have to pass the object reference, if you want to acces a property of it (if the reference isn't already there).

    Do you want to have access from your class to a property of the attribute class, or vica verse, or is it somewhere else?

    If it's access from a member of the Attribute-class to property of class x (in which the attribute is used), you have to pass the object reference (of class x) to the attributes instance (after calling GetCustomAttributes()). The attribute has no information about the classes in which it is used.

    Greetings,


    Wolfgang Kluge
    gehirnwindung.de


    I just need to do the same thing as Microsoft does with the "SoapHeader" attribute. So if you are right (you probably are) the magic has nothing to do with the SoapHeader class, but the System.Web.Services.WebService instance itself...I think that is the conclusion, thanks for your time.

    --
    Werner

    Monday, March 14, 2011 8:30 AM
  •     public class Test
        {
            public void Start()
            {
                Number = 1;
                new Other(this).Begin();
            }
            public int Number { get; set; }
        }

        public class Other
        {
            private Test test;
            //public Other() { }
            public Other(Test test)
            {
                this.test = test;
            }
            public void Begin()
            {
                // I want to get the value of Test.Number, i.e. "1"
            }
        }

    Mark the best replies as answers. "Fooling computers since 1971."

    http://rudedog2.spaces.live.com/default.aspx

    Monday, March 14, 2011 4:47 PM