我已经使用VB.net好几年了,但不断遇到一些我不知道如何解决的怪癖。好奇心终于得到了我的好处,所以我现在问:是否有办法在不指定的情况下创建对象?
例如,假设我有一个Engine类,我想要实例化并让它立即执行它需要做的任何事情。如果在创建引擎之后没有什么我需要做的,我到目前为止做了类似的事情:
将myEngine调暗为新引擎()
有没有办法避免“昏暗的myEngine as”部分?你当然可以用Java。我可以在java中创建一个带有“ new Engine()”的对象,而不是将它分配给任何东西。
为什么我需要这个?因为我经常想要创建一个委托对象(因此我称之为“引擎”)来执行某些功能,但我不需要引用它。我以前有这样的对象有一个“公共子执行”,但发现很麻烦 - 我宁愿只是创建对象而不用担心记得调用它的perform方法。我发现在创建对我不打算使用的对象的引用时,这在美学上是令人不悦的。
任何VB大师都有建议吗?
谢谢,
- 迈克尔
答案 0 :(得分:5)
要执行此操作,您需要将新声明放在圆括号()
中你可以尝试这种语法:
Call New TheClass().Method1()
或:
DoSomething(New TheClass())
甚至:
DoSomething(New TheClass().GetStringData())
来源:http://tutorials.beginners.co.uk/vb-net-programming-part-6-interacting-with-objects.htm
答案 1 :(得分:2)
也许问题是你的设计选择构造函数执行实际工作,而不是把真正的工作放在方法中?构造函数用于从一组或多组参数构建对象的状态。方法执行操作。
静态类确实可以拥有自己的私有方法和字段。当然,不是它们的实例,而是一个可以正常工作的单个“实例”。
您是否可以详细了解这种设计选择/方法的原因,也许我们可以提供一些有关如何更有效地设计对象的见解。
或者,您可以匿名创建对象并通过以下方式调用方法:
Call New obj().method()
答案 2 :(得分:1)
感谢大家的回答。似乎很少有人同意我的特定设计选择,这很好,我很想听听你如何处理这个问题。但首先让我解释为什么我正在做我正在做的事情。
假设我有一个类Exporter,专门用于导出文件。它是一个类,而不是一个模块,因为我可能希望有几个出口商,每个出口商都有自己的设置等等。所以现在我有
将myExporter调暗为新的Exporter()
我的导出器需要提供一些数据,以及要保存的文件名。所以我现在有几个选择:
1)保留空导出器构造函数并添加 myExporter.performExport(数据,文件名)
我不是特别喜欢这个,如果导出器很复杂(我的前提是它 - 否则模块会做得很好),那么我希望它保持自己的状态,这可能是相关的到数据和文件名。重做构造函数更有意义,如选项#2:
2)传递构造函数中的参数:
将myExporter调暗为新的导出程序(数据,文件名)
然后使用简单的无参数调用调用: myExporter.performExport()
这很好,但请注意实质上,即使我宣布myExporter,我只是将其用作一次性调用:创建并执行导出。基本上我不需要引用它,正如@ brian-m建议的那样,我可以做到
调用新的导出程序(数据,文件名).performExport()
(@ code-grey,请注意我现在如何使用没有引用的对象,但这并不是非感性的。)
但是现在我只需每次输入额外的代码 - performExport()部分。如果我知道我将永远想要在对象创建后立即对其进行操作(@ brian-m,我同意 某些情况,当我可能想要准备我的对象然后DELAY执行时,但在其他时候执行也可能在对象创建后立即发生)我也可以将代理代码也放在构造函数中,所以我不担心忘记进行调用。所以现在我有了
将myExporter调暗为新的导出程序(数据,文件名)
不需要进一步调用,因为它在创建后立即导出。从程序的其余部分来看,我不关心导出器一旦完成后会发生什么 - 我并不是故意挂掉垃圾收集,我只是想说我没有必要保持对出口商。
到目前为止一切顺利?如果是这样,那么我希望你们同意我的看法,摆脱“昏暗的myExporter as”部分更加有意义,只留下“新的出口商(数据,文件名)” 。除了Java之外,与Java不同,似乎不允许这样做。
感谢阅读,我期待听到您的建议。
- 迈克尔
答案 3 :(得分:0)
也许你可以在模块中声明你的全局对象......
Module GlobalModule
Public x As Double = 110
Public myObject As AutonomousObject = New AutonomousObject() ' This will instantiate the object
End Module
...创建一个类......
Public Class AutonomousObject
Public Sub New()
MessageBox.Show("Hello, I was instantiated now. " + System.Reflection.MethodBase.GetCurrentMethod().Name)
End Sub
Public Sub Start()
MessageBox.Show("Hello, I am initialized! " + System.Reflection.MethodBase.GetCurrentMethod().Name)
End Sub
End Class
...然后从任何地方使用它,而无需再次实例化
Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click
MessageBox.Show(GlobalModule.x) ' Will display 110
' OR
GlobalModule.myObject.Start() ' This will call a method that will display a message
End Sub
答案 4 :(得分:0)
有时,对象的构造函数会将对象“连接”到作为参数传递的另一个对象,并且调用构造函数的代码将不再用于对象引用。我建议忽略结果的“新”调用不应该在类之外使用,而是类应该提供类似的包装方法:
Sub AddNewItemToList(TheList as MyListType, TheData as DataToGoInNewItem) GC.KeepAlive(New MyListNode(TheList, TheData)) End Sub
GC.KeepAlive方法实际上可以称为“GC.PretendToUseTheParameterButDontActuallyDoAnythingWithIt”,这正是您在这里寻找的语义。
答案 5 :(得分:0)
如果我理解正确的话,那么即使你不想使用它,你也试图避免被实例化的对象用尽的内存。 如果是这样,那么为什么不使用Singleton Object。这只是实例化一次,第一次调用时。
答案 6 :(得分:0)
您可以在班级上使用虚拟方法,并使用上述解决方案和Call关键字
Call (New Engine()).dummy()
为了增加趣味,您可以在任何现有类上创建虚拟扩展方法
或者您可以在不修改任何内容的情况下将反射用于代码的一行
GetType(Engine).GetConstructor(types:= New Type(){} ).Invoke(parameters:= New Object(){})
不过,您可以将我添加到不同意您在构造函数中执行重要工作的设计选择的人员列表中。