views:

85

answers:

4

So I want a pointer to a pointer.

I've got a class that is updated in one object. In another object I want a reference to the current version of the object in the original Class. Here is sort of a simplified version of what I have going on.

Public Class Foo
    'conaints information

End Class

Public Class myMainApp
    Dim myHelper As HelperClass
    Dim currentFoo As Foo

    Private Sub init()
        currentFoo = New Foo()
        myHelper = New HelperClass(currentFoo)
    End Sub

    Private Sub UpdatingUI()
        currentFoo = GetFooFromContext()
    End Sub

    Private Function GetFooFromContext() As Foo
        Return New Foo()
    End Function
End Class


Public Class HelperClass
    Private myFoo As Foo

    Public Sub New(ByVal aFoo As Foo)
        myFoo = aFoo
    End Sub
End Class

if thise was C++, currentFoo would be a Foo* and HelperClass's myFoo would be a Foo** so that whenever we updated currentFoo's refrence to a new object the HelperClass would also be accessing this new object.

Is there syntax to accomplish this in the .net world?

+3  A: 

There isn't a direct equivalent to this.

The best option is usually to have your HelperClass actually keep a reference to your main class, and read/write Foo as needed from a property on your main class. This way, it has a reference to the class that holds Foo, instead of Foo itself. This is still not the same, though, since if you change the main classes "Foo" instance, you'll lose the reference to the original (unless you've saved that, as well).

Reed Copsey
I can see how that would be a good idea, but in this praticular case the main class is a form with LOTS of stuff in it, and I only need a few objects out of it.Having access to the main form could be really dangerous for the next guy.
Joel Barsotti
Use an interface, then. If the main class implements an interface, you can use that to just expose the specific properties you wish, and pass the form in as the interface instead of as it's class.
Reed Copsey
One other option in that scenario is to define an interface with only the properties that you need from the form, have the form implement it, and use a reference to said interface in `HelperClass`. This would make the amount of coupling explicit and thus clear. Of course, one would still be able to cast the interface reference to the original class, but a person doing that would at least have to make an effort in doing so, and hopefully stop and think what they're doing.
Pavel Minaev
That interface idea is very cool I may indeed end up using that, or something like that.Deffinetly something I'll try to stow away in my mental toolbox.
Joel Barsotti
A: 

Stop Thinking About Pointers

yes, you could do exactly what you're thinking in C# using unsafe code - but seriously, don't.

Reed's advice is the best so far; i suspect with more context we could suggest a better solution, for example:

  • use a property for currentfoo
  • when currentfoo's value is set, change the value of the foo property of the helper class

mostly i just wanted to emphasize the omg-don't-do-that aspect of this question ;-)

Steven A. Lowe
You can't do it using unsafe, actually, since even unsafe won't let you declare raw pointers to managed types (an object reference is a managed type).
Pavel Minaev
@[Pavel Minaev]: I stand corrected, thanks - all the more reason to stop thinking about pointers!
Steven A. Lowe
+1  A: 

Reed's answer is the typical idiomatic C# way to handle this, but if you really want it, you can always just introduce your own "reference wrapper" helper class:

public class Reference<T> where T : class
{
    public T Value { get; set; }
}

Then declare both currentFoo and myFoo as Reference<Foo>, and also make sure that currentFoo is readonly, so that no-one can assign a different Reference to it.

Pavel Minaev
Pavel Minaev
A: 

You need to share a reference to a class that has Foo as a property. Sorry to write in C#;-)

class MyMainApp
    {
        private HelperClass myHelper;
        private FooBar myFooBar;

        public void Init()
        {
            myFooBar=new FooBar(new Foo());
            myHelper=new HelperClass(myFooBar);
        }

        public void UpdateFromUI()
        {
            myFooBar.CurrentFoo = GetFooFromContext();
            myHelper.DoSomethingWithTheFoo();
        }

        private Foo GetFooFromContext()
        {
            return new Foo();
        }
    }

    class FooBar
    {
        public Foo CurrentFoo;

        public FooBar(Foo new_foo)
        {
            CurrentFoo = new_foo;
        }
    }

    class HelperClass
    {
        private FooBar myFooBar;

        public HelperClass(FooBar new_foobar)
        {
            myFooBar = new_foobar;

        }

        public void DoSomethingWithTheFoo()
        {
            myFooBar.CurrentFoo.JumpThroughHoop();
        }
    }

    class Foo
    {
        public void JumpThroughHoop()
        {}
    }
Dabblernl
Ah yes everything works better with one more level of abstraction.I see how this is much closer to how I want my app to work, with myFooBar holding all the Context info I need.Unfortunetly everything is setup without that layer inbetween, so it's going to require alot more work to restructure the app to work like that, but probably is the solution.
Joel Barsotti