共享方法问题“全局”存储 [英] Shared Method Problem With "Global" Storage

查看:56
本文介绍了共享方法问题“全局”存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对共享方法有这个令人讨厌的问题,我认为这是全球

存储的问题。 - 即在任何子程序或函数之外声明的存储。

在下面的简单示例中,global存储是ButtonHasBeenClicked。

在这个简单的示例中,Form1中的代码调用Module1中的例程,然后

调用Form1中的代码(子例程WhatEver)。 WhatEver需要访问

ButtonHasBeenClicked但对ButtonHasBeenClicked的引用导致

注释中反映的错误。我没有看到任何模糊的东西我想要做什么。我怀疑有一些合成解决方案,但我已经无法找到它。


非常感谢您提供的任何解决方案和/或理解。


Bob


公共类Form1

继承System.Windows.Forms.Form

Dim ButtonHasBeenClicked As Boolean


#Region" Windows窗体设计器生成的代码

#End Region

Private Sub Button1_Click(ByVal sender As System.Object,ByVal e As

System.EventArgs)处理Button1.Click

ButtonHasBeenClicked = True

End Sub


Public Shared Sub WhatEver()<如果没有
$ b b一个明确的班级实例。


''做一件事

否则''做别的事情

结束如果


End Sub


Private Sub Button2_Click(ByVal sender As System.Object,ByVal e As

System.EventArgs )处理Button2.Click

CalculateSomething()


如果ButtonHasBeenClicked那么

''在这里做点什么;没有问题引用ButtonHasBeenClicked

这里

结束如果

结束子


结束班

模块模块1

Public Sub CalculateSomething()

Form1.WhatEver()

End Sub

结束模块

解决方案

" eBob.com" < eB ****** @ totallybogus.comschrieb


我对共享方法有这个令人讨厌的问题,我认为是

全球存储 - 即在任何子程序之外声明的存储

或函数。



它被称为字段。


在下面的简单示例中;全球"存储是

ButtonHasBeenClicked。在这个简单的示例中,Form1中的代码在Module1中调用

例程,然后在Form1中调用代码(子例程

WhatEver)。 WhatEver需要访问ButtonHasBeenClicked,但对ButtonHasBeenClicked的

引用导致错误反映在

注释中。在我想要做的事情上,我没有看到任何含糊之处。我b $ b怀疑有一些合成解决方案,但我一直无法找到它。$ / b

非常感谢任何解决方案和/或了解你可以

提供。


Bob


公共舱Form1

继承System.Windows.Forms.Form


Dim ButtonHasBeenClicked As Boolean



如果它不是Shared,则每个实例都是表格在这个

字段中具有它自己的价值。


Public Shared Sub WhatEver()


如果ButtonHasBeenClicked那么''无法引用一个实例

共享方法或共享成员中的一个类成员

初始化者没有类的显式实例。



在共享Sub中,如果没有对该对象的

引用,则无法访问实例字段。您要访问哪个实例的字段?

或者甚至可能没有创建一个实例。因此失败了。不要
将Sub声明为共享。


''做一件事

Else''做其他事情

结束如果


结束Sub


模块模块1

Public Sub CalculateSomething()

Form1.WhatEver()

End Sub

结束模块



如果您想访问模块中的表单,则必须将表单

传递给该过程。最好不要访问模块中的表单。为什么不把你的代码放入表格中?
如果要重用模块中的代码,

对程序的目的进行抽象定义,传入和传出所需的

数据,并将其调用来自表格。

Armin


10月19日上午11:01,eBob.com < eBob .... @ totallybogus.comwrote:


我对共享方法有这个令人讨厌的问题,我认为是global

存储" - 即在任何子程序或函数之外声明的存储。

在下面的简单示例中,global存储是ButtonHasBeenClicked。

在这个简单的示例中,Form1中的代码调用Module1中的例程,然后

调用Form1中的代码(子例程WhatEver)。 WhatEver需要访问

ButtonHasBeenClicked但对ButtonHasBeenClicked的引用导致

注释中反映的错误。我没有看到任何模糊的东西我想要做什么。我怀疑有一些合成解决方案,但我已经无法找到它。


非常感谢您提供的任何解决方案和/或理解。


Bob


公共类Form1

继承System.Windows.Forms.Form

Dim ButtonHasBeenClicked As Boolean


#Region" Windows窗体设计器生成的代码

#End Region

Private Sub Button1_Click(ByVal sender As System.Object,ByVal e As

System.EventArgs)处理Button1.Click

ButtonHasBeenClicked = True

End Sub


Public Shared Sub WhatEver()<如果没有
$ b b该类的显式实例。



错误消息的含义完全正确。您试图将

引用到实例变量 - 在共享方法中与类的特定实例相关联的变量。共享方法是

与类的任何特定实例无关。与班级本身相关的是
。 VB有点隐藏这种区别

,它允许你通过

实例变量调用共享方法这一可疑功能(C#将从版本3.0开始分享这一荣誉) )。


无论如何,以上所有意味着你无法访问

ButtonHasBeen以你正在尝试的方式点击,因为共享

方法不知道哪个版本的ButtonHasBeen点击了

参考...


这意味着你需要:


1)将ButtonHasBeenClicked声明为共享,这意味着如果您有多个表格实例
- 所有这些实例将共享相同的

ButtonHasBeenClicked,这可能不是你想要的。


2)从sub中删除共享修饰符,以便它是一个成员

方法(这个意味着有一个隐含的Me引用传递给

子/函数 - 这意味着你可以参考

ButtonH asBeenClicked变量就像你现在做的那样。


3)保持你的子/功能共享,但是让它取一个参数

指定你感兴趣的实例:sub somesub(byval

theForm as myform)。然后你可以使用那个实例变量得到一个ButtonHasBeenClicked的




就个人而言,如果这个子/函数没有<我可能会使用#2 br />
超出您特定表格的实用程序。并且不要认为这将会导致多个版本的funciton / sub同时存在于内存中

(我之前见过有人关注此事) ) - 因为它不会。该类的所有

实例仍然调用相同的代码,但编译器将额外的参数添加到funciton sub,这需要

实例....


无论如何,HTH

-

Tom Shelton


您好Armin,感谢您的回复。请看下面我的进一步问题

穿插代码和你的意见...


-----原始消息-----

来自:Armin Zingler < az ******* @ freenet.de>

新闻组:microsoft.public.dotnet.languages.vb

发送日期:2007年10月19日,星期五下午1:19

主题:回复:共享方法问题全局存储


" eBob.com" < eB ****** @ totallybogus.comschrieb


>我对共享方法有这个令人讨厌的问题,我认为是
" ;全球存储 - 即在任何子程序或功能之外声明的存储。



它被称为字段。


>在下面的简单示例中这个全球存储是ButtonHasBeenClicked。在这个简单的示例中,Form1中的代码调用Module1中的
例程,然后在Form1中调用代码(子例程
WhatEver)。 WhatEver需要访问ButtonHasBeenClicked但是对ButtonHasBeenClicked的
引用会导致注释中反映的错误。在我想要做的事情上,我没有看到任何含糊之处。我怀疑有一些合成解决方案,但我一直无法找到它。

非常感谢您提供的任何解决方案和/或理解。

Bob

Public Class Form1
继承System.Windows.Forms.Form

Dim ButtonHasBeenClicked As Boolean



如果它不是共享的,那么表格的每个实例在这个

字段中都有它自己的值。


> Public Shared Sub WhatEver()

如果ButtonHasBeenClicked然后''无法从共享方法或共享成员中引用类的实例
初始化程序而没有显式实例班级。




在共享Sub中,如果没有对该对象的

引用,则无法访问实例字段。你想要哪个实例的字段

访问?

或者甚至可能没有创建一个实例。因此,这失败了。

不要

将Sub声明为Shared。



但是如果我没有制作WhatEver Shared,那么我就不能从Module1

代码中调用它。


有两件事可能会导致我在这方面的困惑。 1)在我正在开发的真正的

项目中

我使用模块只是为了让代码更易于管理。应用程序

正在挖掘一些网站

,我为每个站点使用不同的模块。所有

站点共有的代码在Form1.vb代码中。

和2)显然可以有多个Form1,但我看到Form1为

与我运行的

申请相关联。这是最重要的事情。对于我写的

(非常简单)的应用程序,它不会有任何意义。

不止一个。


我没有得到的是,如果我在Form1.vb

代码中的子程序

中引用ButtonHasBeenClicked,则毫无疑问正在引用哪个实例。但是当我在一个模块中调用(来自Form1.vb代码)一个子程序

时,

.Net突然不知道代码是什么实例

正在努力。我可以通过简单地将

模块中的子程序剪切并粘贴到Form1.vb代码来解决这个问题,

对吗? (但是我的Form1.vb代码会变得难以管理。)


我现在看到的部分问题是我误解了并且误用了

模块概念。对?但你怎么做?
保持代码文件的大小和组织更易于管理?我需要一些

的方法来隔离挖掘网站A所特有的代码,这个代码是采矿网站B独有的

代码。


抱歉在你肩膀上哭泣。我对VB.Net的了解是

自学成才,我理解中存在重大漏洞。


谢谢,Bob


>


> ''做一件事
否则'做别的事
结束如果

结束Sub



>模块模块1
Public Sub CalculateSomething()
Form1.WhatEver()
End Sub
结束模块



如果您想访问模块中的表单,则必须将

表格

传递给该程序。最好不要访问模块中的表单。为什么

没有

你把代码放入表格?如果要重用模块中的代码,

对程序的目的进行抽象定义,传入和传出


$ b需要$ b数据,并从表格中调用。


Armin



I have this nasty problem with Shared methods and what I think of as "global
storage" - i.e. storage declared outside of any subroutines or functions.
In the simple example below this "global" storage is ButtonHasBeenClicked.
In this simple example code in Form1 calls a routine in Module1 which then
calls code back in Form1 (subroutine WhatEver). WhatEver needs to access
ButtonHasBeenClicked but the reference to ButtonHasBeenClicked results in
the error reflected in the comment. I don''t see any ambiguity in what I am
trying to do. I suspect there is some syntatic solution but I have been
unable to find it.

Thanks much for whatever solution and/or understanding you can provide.

Bob

Public Class Form1
Inherits System.Windows.Forms.Form

Dim ButtonHasBeenClicked As Boolean

#Region " Windows Form Designer generated code "
#End Region

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
ButtonHasBeenClicked = True
End Sub

Public Shared Sub WhatEver()

If ButtonHasBeenClicked Then '' Cannot refer to an instance member
of a class from within a shared method or shared member initializer without
an explicit instance of the class.

''do one thing
Else ''do something else
End If

End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click
CalculateSomething()

If ButtonHasBeenClicked Then
''do something here; no problem referencing ButtonHasBeenClicked
here
End If
End Sub

End Class

Module Module1
Public Sub CalculateSomething()
Form1.WhatEver()
End Sub
End Module

解决方案

"eBob.com" <eB******@totallybogus.comschrieb

I have this nasty problem with Shared methods and what I think of as
"global storage" - i.e. storage declared outside of any subroutines
or functions.

It''s called a "field".

In the simple example below this "global" storage is
ButtonHasBeenClicked. In this simple example code in Form1 calls a
routine in Module1 which then calls code back in Form1 (subroutine
WhatEver). WhatEver needs to access ButtonHasBeenClicked but the
reference to ButtonHasBeenClicked results in the error reflected in
the comment. I don''t see any ambiguity in what I am trying to do. I
suspect there is some syntatic solution but I have been unable to
find it.

Thanks much for whatever solution and/or understanding you can
provide.

Bob

Public Class Form1
Inherits System.Windows.Forms.Form

Dim ButtonHasBeenClicked As Boolean


If it is not Shared, every instance of the Form has it''s own value in this
field.

Public Shared Sub WhatEver()

If ButtonHasBeenClicked Then '' Cannot refer to an instance
member of a class from within a shared method or shared member
initializer without an explicit instance of the class.


In a shared Sub, you can not access an instance field withouth having a
reference to the object. The field of which instance do you want to access?
Or maybe not even one instance has been created. Therefore this fails. Don''t
declare the Sub as Shared.

''do one thing
Else ''do something else
End If

End Sub

Module Module1
Public Sub CalculateSomething()
Form1.WhatEver()
End Sub
End Module

If you wanted to access a Form in a Module, you would have to pass the Form
to the procedure. It is better not to access the Form in a Module. Why don''t
you put the code into the Form? If the code in the Module is to be reused,
make an abstract definition of the procedure''s purpose, pass in and out the
data needed, and call it from the Form.
Armin


On Oct 19, 11:01 am, "eBob.com" <eBob....@totallybogus.comwrote:

I have this nasty problem with Shared methods and what I think of as "global
storage" - i.e. storage declared outside of any subroutines or functions.
In the simple example below this "global" storage is ButtonHasBeenClicked.
In this simple example code in Form1 calls a routine in Module1 which then
calls code back in Form1 (subroutine WhatEver). WhatEver needs to access
ButtonHasBeenClicked but the reference to ButtonHasBeenClicked results in
the error reflected in the comment. I don''t see any ambiguity in what I am
trying to do. I suspect there is some syntatic solution but I have been
unable to find it.

Thanks much for whatever solution and/or understanding you can provide.

Bob

Public Class Form1
Inherits System.Windows.Forms.Form

Dim ButtonHasBeenClicked As Boolean

#Region " Windows Form Designer generated code "
#End Region

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
ButtonHasBeenClicked = True
End Sub

Public Shared Sub WhatEver()

If ButtonHasBeenClicked Then '' Cannot refer to an instance member
of a class from within a shared method or shared member initializer without
an explicit instance of the class.

The error message means EXACTLY what it says. You are trying to refer
to an instance variable - a variable that is associated with a
specific instance of a class, in a shared method. A shared method is
NOT associated with any particular instance of a class. It is
associated with the class itself. VB sort of hides this distinction
with it''s dubious feature of allowing you to call shared methods via
instance variables (an honor that C# will share as of version 3.0).

Anyway, what all of the above means is that you can not access
ButtonHasBeenClicked in the manner you are attempting, since a shared
method has NO knowledge of which version of ButtonHasBeenClicked to
reference...

What this means is that you need to:

1) declare ButtonHasBeenClicked as shared, which means if you have
multiple instances of your form - all of them will share the same
ButtonHasBeenClicked, which is probably not what you want.

2) Remove the shared modifier from the sub, so that it is a member
method (this means that there is an implicit Me reference passed to
the sub/function - which means you can then refer to the
ButtonHasBeenClicked variable as your doing now.

3) Keep your sub/function shared, but make it take a parameter that
specifies the instance you are interested in: sub somesub (byval
theForm as myform). Then you can use that instance variable to get a
hold of ButtonHasBeenClicked.

Personally, I would probably use #2 if this sub/function has no
utility beyond your specific form. And don''t think that this will
cause multiple versions of the funciton/sub to be in memory at once
(I''ve seen people concerned by this before) - because it won''t. All
instances of the class still call the same code, but the compiler adds
a additional parameter to the funciton sub, that takes the
instance....

Anyway, HTH

--
Tom Shelton


Hi Armin, Thanks for your response. Please see my further question below
interspersed with the code and your comments ...

----- Original Message -----
From: "Armin Zingler" <az*******@freenet.de>
Newsgroups: microsoft.public.dotnet.languages.vb
Sent: Friday, October 19, 2007 1:19 PM
Subject: Re: Shared Method Problem With "Global" Storage

"eBob.com" <eB******@totallybogus.comschrieb

>I have this nasty problem with Shared methods and what I think of as
"global storage" - i.e. storage declared outside of any subroutines
or functions.


It''s called a "field".

>In the simple example below this "global" storage is
ButtonHasBeenClicked. In this simple example code in Form1 calls a
routine in Module1 which then calls code back in Form1 (subroutine
WhatEver). WhatEver needs to access ButtonHasBeenClicked but the
reference to ButtonHasBeenClicked results in the error reflected in
the comment. I don''t see any ambiguity in what I am trying to do. I
suspect there is some syntatic solution but I have been unable to
find it.

Thanks much for whatever solution and/or understanding you can
provide.

Bob

Public Class Form1
Inherits System.Windows.Forms.Form

Dim ButtonHasBeenClicked As Boolean



If it is not Shared, every instance of the Form has it''s own value in this
field.

> Public Shared Sub WhatEver()

If ButtonHasBeenClicked Then '' Cannot refer to an instance
member of a class from within a shared method or shared member
initializer without an explicit instance of the class.



In a shared Sub, you can not access an instance field withouth having a
reference to the object. The field of which instance do you want to
access?
Or maybe not even one instance has been created. Therefore this fails.
Don''t
declare the Sub as Shared.

But if I don''t make WhatEver Shared then I can''t call it from the Module1
code.

Two things probably contribute to my confusion in this area. 1) In the real
project I am working on
I am using Modules simply to keep the code more manageable. The application
is mining some web sites
and I use a different Module for each site. Code which is common to all
sites is in the Form1.vb code.
And 2) apparently there can be more than one Form1, but I see Form1 as being
associated with my running
application. It''s the "topmost thing". It wouldn''t make any sense, for the
(admitedly simple) applications I''ve written, to have
more than one.

What I don''t get is that if I refer to ButtonHasBeenClicked in a subroutine
in the Form1.vb
code there is no question about which instance is being referenced. But
when I call (from the Form1.vb code) a subroutine
in a Module, .Net suddenly has no knowledge of what instance the code is
working on. I can
solve this problem by simply cutting and pasting the subroutine in the
Module to the Form1.vb code,
right? (But then my Form1.vb code would get unmanageably large.)

Part of my problem, I see now, is that I have misunderstood and am misusing
the Module concept. Right? But what do you do to
keep the size and organization of code files more manageable? I need some
way to segregate the code which is unique to mining web site A from the
code which is unique to mining web site B.

Sorry to be crying on your shoulder. What I know about VB.Net is
self-taught and there are major holes in my understanding.

Thanks, Bob

>

> ''do one thing
Else ''do something else
End If

End Sub


>Module Module1
Public Sub CalculateSomething()
Form1.WhatEver()
End Sub
End Module


If you wanted to access a Form in a Module, you would have to pass the
Form
to the procedure. It is better not to access the Form in a Module. Why
don''t
you put the code into the Form? If the code in the Module is to be reused,
make an abstract definition of the procedure''s purpose, pass in and out
the
data needed, and call it from the Form.
Armin



这篇关于共享方法问题“全局”存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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