2009-09-18 3 views
1

Так что я хочу указатель на указатель.Ссылка на тип refrence в .net?

У меня есть класс, который обновляется в одном объекте. В другом объекте я хочу ссылку на текущую версию объекта в исходном классе. Вот своего рода упрощенная версия того, что у меня происходит.

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 

если ДАННОЕ был C++, currentFoo будет Foo * и MYFOO вспомогательного класса был бы быть Foo **, так что всякий раз, когда мы обновили refrence currentFoo к новому объекта, вспомогательный класс также будет доступ к этому новому объекту.

Есть ли синтаксис для достижения этого в мире .net?

ответ

1

ответ Рида типичный идиоматических C# способ справиться с этим, но если вы действительно хотите, вы всегда можно просто ввести свой собственный «ссылка обертку» вспомогательный класс:

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

Затем объявить как currentFoo и myFoo как Reference<Foo>, а также убедитесь, что currentFoo является readonly, так что никто не может назначить другой Reference к нему ,

+0

Для быстрого и грязного одноразового решения (или если у вас нет дженериков, т. Е. .NET 1.x), использование одноэлементного массива также будет работать, хотя было бы менее понятно. –

3

Не существует прямого эквивалента этому.

Лучшим вариантом обычно является то, что ваш HelperClass фактически содержит ссылку на ваш основной класс и читает/записывает Foo по мере необходимости из свойства вашего основного класса. Таким образом, он имеет ссылку на класс, который содержит Foo, а не сам Foo. Это все равно не то же самое, поскольку, если вы измените экземпляр основного класса «Foo», вы потеряете ссылку на оригинал (если вы не сохранили это тоже).

+0

я могу видеть, как это было бы хорошей идеей, но в этом случае praticular основной класс является формой с большим количеством материала в нем, и мне нужно только несколько объектов из него. Доступ к основной форме может быть действительно опасен для следующего парня. –

+0

Используйте интерфейс. Если основной класс реализует интерфейс, вы можете использовать его, чтобы просто выставить конкретные свойства, которые хотите, и передать форму как интерфейс, а не как класс. –

+0

Еще один вариант в этом сценарии - это определить интерфейс с только теми свойствами, которые вам нужны из формы, иметь форму, реализующую его, и использовать ссылку на указанный интерфейс в 'HelperClass'. Это сделало бы ясность и, следовательно, ясным. Конечно, все равно можно было бы передать ссылку на интерфейс оригинальному классу, но человек, делающий это, по крайней мере должен был бы приложить усилия для этого и, надеюсь, остановиться и подумать, что они делают. –

0

перестать думать о легавых

да, вы могли бы делать то, что вы думаете, в C# с использованием небезопасного кода - но серьезно, не.

Рекомендации Рида являются лучшими до сих пор; я подозреваю, что с более контексте мы могли бы предложить лучшее решение, например:

  • использовать свойство для currentfoo
  • когда значение currentfoo имеет значение, измените значение Foo свойства класса хелперов

в основном я просто хотел бы подчеркнуть OMG-не-делать-что аспект этого вопроса ;-)

+1

Вы не можете сделать это с помощью небезопасного, фактически, так как даже небезопасное не позволит вам объявлять необработанные указатели на управляемые типы (ссылка на объект - это управляемый тип). –

+0

@ [Павел Минаев]: Я стою исправленный, спасибо - тем более причина перестать думать о указателях! –

0

Вам необходимо предоставить ссылку на класс, в котором есть Foo. Извините, писать в 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() 
     {} 
    } 
+0

Ах да все работает лучше с еще одним уровнем абстракции. Я вижу, как это намного ближе к тому, как я хочу, чтобы мое приложение работало, и myFooBar держал всю необходимую информацию контекста. К сожалению, все настроено без этого слоя между ними, поэтому потребуется много работы по реструктуризации приложения, чтобы работать так, но, вероятно, это решение. –

Смежные вопросы