2

C++ では、次のことが可能です。

int x;
int& foo = x;

// foo is now a reference to x so this sets x to 56
foo = 56;

しかし、Visual Basic .net (VB.net) で同等のことが可能ですか?

私はByRefVB.netの用語を知っていますが、関数/サブルーチンへの参照によってパラメーターを渡すことでこれを見ただけで(そして広範な調査によって)、関数が呼び出し元のコードによって宣言された同じ変数を変更します。

ByRefしかし、変数を (クラス メンバーまたはローカル変数として) 宣言するために使用されたものは見たことがありません。このような宣言を行うために使用しようとしましたが、試みByRefた宣言の順序ごとにコンパイラ エラーが発生します。

これを行う理由は、クラス インスタンスが別のクラス インスタンスで宣言された変数を参照できるようにするためです。

具体的には、プログラム ロジックが VB.net フォーム クラスの UI ロジックと混同されている既存の VB.net コードに取り組んでいます。プログラム ロジックをフォーム コードから分離して、より簡単に再利用できるようにしたいと考えています。これを行うには、プログラム ロジック コードがフォーム コードと「対話」できるようにする必要があるため、その変数にアクセスする必要があります。

私は VB.net で Visual Studio 2010 Express を使用しており、完全な Visual Studio には機能が拡張されていることを認識していますが、この環境にとどまりたいと考えています。

4

4 に答える 4

2

こんにちは、VB.NETについてはよくわかりませんが、C#でそれを行う方法を知っているので、C#でソリューションを実行し、C#からVB.NETへのコンバーターを使用してVB.NETコードを取得しました。多分それはあなたを助けるかもしれません:

http://www.developerfusion.com/tools/convert/csharp-to-vb/

C# コード

protected void TestFoo()
{

    string strFooA = string.Empty;

    GetFoo(ref strFooA);

    Response.Write(strFooA);
}

private void GetFoo(ref string strFooA)
{
    strFooA = "FooA";
}

VB.NET 変換

    Protected Sub TestFoo()

      Dim strFooA As String = String.Empty

      GetFoo(strFooA)

      Response.Write(strFooA)
    End Sub

    Private Sub GetFoo(ByRef strFooA As String)
      strFooA = "FooA"
    End Sub
于 2012-07-10T14:34:46.823 に答える
2

ポインターは存在しますが、それらはオブジェクト参照と呼ばれます

(他のポスターの皆さん、ここでの実際の違いについて私と口論しないでください。私は、OPが達成したい高レベルのタスクについて話しているのです)

明らかに、あなたが言ったことを文字通り実行することはできません-つまり、1つのメンバーを外科的に操作します. しかし、コードを制御できる場合は、ほとんど同じことができます。そして、あなたが説明していることから、この方法は、多くの個々のポインターを渡す代わりに、更新したい多くのメンバーを持つオブジェクトへの参照を渡すことができるため、はるかに優れています。

最初にクラスを定義します。

Class MyScreenValues
    ' Properties will work... using public fields for brevity
    Public TextBox1Value as String
    Public SpinControl1Value as Integer
    public CheckBox1Value as Boolean
End Class

投稿したコードに相当するもの:

Dim x as new MyScreenValues    'int x; 
dim foo as MyScreenValues = x  'int& foo = x;  
'// c++:  foo is now a reference to x so this sets x to 56 
'// .net: foo is now a reference to x so this sets x.SpinControl1Value to 56 
foo.SpinControl1Value = 56; 

あなたがやっていることは、たとえば、フォームの値のすべてのコントロールへのポインターをサブに渡そうとしている場合、次のようになります。

Button1_Click(...
    Dim MyObject as new BusinessObject
    MyObject.DoSubmit(TextBox1.Text, SpinButton1.Value, CheckBox1.Checked)

superDeveloper が提供するメソッドを使用して、DoSubmit Sub の定義で ByRef キーワードを使用できます。

Public Sub DoSubmit(ByRef Name as String, ByRef Age as Integer, ByRef Employed as boolean)
    ... business logic...

ただし、これでは 2 層の分離が得られます。MVP、MVC などを調べてください。ただし、ビュー全体に相当するデータを送信することを検討してください。あなたが今持っているもので解決できるのは、多くの研究です。たとえば、フォームの値が変更されると、ビジネス ロジックはフォーム上でイベントを発生させます (実際には、VB が byref プロパティ [=一時変数] を処理する方法により、サブが終了するまでイベントは発生しませんが、考慮する必要があります)。

他のライブラリを使用して、オブジェクトのプロパティをフォームのプロパティにマップすることもできます。ウェブでVALUE INJECTORをチェックしてください。Webフォーム/Winフォーム、さらにはWPFフォームを取り、定義済みのオブジェクトとの間でコントロール値をマップできます。完全な分離に優れています。

于 2012-07-10T15:11:25.043 に答える
1

ポインターは、C/C++ の場合のように .NET フレームワークには存在しないため、目的を直接達成することはできません。

このSOページにはいくつかの可能な解決策があります

そこで@NathanWの回答を参照してください:

VB を使用している場合、ポインタに本当に近いのは IntPtr だけです。C# にアクセスできる場合は、安全でない C# コードを使用してポインター作業を行うことができます。

更に

参照を使用できるようにしたい場合は、クラスを使用してこれを実現できます。

Private Class RefClass
    Public x As Integer
End Class

次に、一方から他方を参照できます。

Dim bar As New RefClass
Dim foo As RefClass = bar

bar.x = 45

Debug.WriteLine(bar.x) 'outputs 45
Debug.WriteLine(foo.x) 'outputs 45
于 2012-07-10T14:47:09.187 に答える
1

http://www.dreamincode.net/forums/topic/135354-reference-types-value-types-byval-byref/の情報から、仕事を成し遂げるのに十分な知識があるかもしれません。ただし、「ローカル変数(およびおそらくクラス変数)の宣言ではByRefは必要ありません」という発言により、ここで混乱があるのではないかと思いました。

まず、上記の C++ の例でint x; int& foo = x;は、「参照」の意味が混乱しています。私の C++ はあまり強力ではありませんが、意味的に言えば、この C++ リファレンスはエイリアシング メカニズムのように機能すると思います。VB (および C#) では、参照はメモリ内のクラスのインスタンスを特定する識別コードのように機能します。VB にも C# にも、C++ 参照型のようなものはありません。

フォームを ByVal パラメーターとして渡し、そのプロパティとフィールドを問題なく変更できることは既にご存じでしょう。(ByVal は VB.NET の既定値であるため、これを使用する必要さえありません。VB6 では ByRef が既定値でした)。しかし、ええ、.NET 参照変数の場合、次のように仮定します。

Dim objA as New MyClass()
Dim objB as MyClass = objA

次に、objA と objB の両方が MyClass のまったく同じインスタンスを参照します。objA と objB を介して変更でき、objA または objB から読み取ることができます。これは、それぞれがまったく同じインスタンスに影響を与えるためです。objA または objB のいずれかをサブルーチン Foo にパラメータ objC As Object passed ByVal (つまりSub Foo(ByVal objC As Object)) で渡すことができ、Foo は同じインスタンスを変更することもできます。


ByRefVB の およびC ref# の は、変更可能なパラメーターを示します。これは、値の代わりに何らかの「識別コード」参照が渡されることを意味します。それでも、この ByVal と ByRef のことは泥のように明らかです。.NET では、「値」型と「参照」型が区別され、ByReforrefが必要かどうかで多くの人が混乱するからです。

Visual Basic と C# は、変数 (およびデータ型) を「値」(または「構造」) と「参照」(または「クラス」) の 2 種類に二分します。

「値」タイプは、整数、ブール値、ビットマップ、またはその他の種類のオブジェクトを表すビットの実際のコレクションを意味します。古い学校の用語では、これはオブジェクトのインスタンス化の「イメージ」です。オブジェクトの状態空間です。それは、メモリ内のどこにあるかに関係なく、オブジェクトを本質的にそれ自体にするものです。

「参照」型とは、オブジェクトのデータ型とメモリ内の場所を何らかの形で示すコード (整数またはポインターのように見える) を意味します。コンピュータは「リファレンス」を解釈して、オブジェクトの実際のイメージ (つまり、その「値」) を取得します。

「値」パラメーターが渡さByValれると、渡される元の式と同じイメージである新しいオブジェクトが作成され、関数またはメソッドが動作するのはこのコピー上にあることを意味します。「Value」の元のイメージに影響を与えることはできません。

「値」パラメーターが渡さByRefれると、新しい「参照」変数が作成され、その「参照」変数には、元の「値」のイメージに解釈される情報が含まれます。「値」の元のイメージを変更できるようになりました。

「参照」パラメーターが渡さByValれると、その「識別コード」がオブジェクトの実際の画像に解釈されてコピーされます。関数、サブルーチン、またはメソッドが動作するのは、このコードのコピーに対してです。このコピーは、まだオブジェクトの実際の画像を指しています。つまり、渡された Reference 変数のオブジェクトは、ByValそのイメージ (つまり、「値」) を変更することができます。ただし、元の「参照」自体のコードを変更することはできません。

(String 型は奇妙なダックであることに注意してください。実際には「参照」型であっても、「値」パラメータであるかのように動作します。したがって、ByVal で渡された String は、他の型と同じようには影響を受けません。実際、String は不変型の例です - つまり、その「値」が変更されないようにするための措置が講じられています。)

「参照」パラメーターが渡さByRefれると、元の「参照」オブジェクトを指す新しい「参照」オブジェクトが作成されます (これは、「識別コード」を介して他のオブジェクトの「値」を指します)。 )。「参照」で を使用するByRefと、パラメータとして渡される元の「参照」オブジェクトの「識別コード」を変更 (または新しく作成) できます。スワップ操作を実行する関数、サブルーチン、またはメソッドは、「参照」パラメーターで ByRef を使用します。

于 2012-07-10T20:48:31.933 に答える