如何实例化对象并将其传递给 "using" 块声明中的方法
How to instantiate an object and pass it to a method within the declaration of a "using" block
我正在使用实现 IDisposable 的外部 class 和填充该 class 实例的外部方法。
我正在寻找一种将一次性对象封装在 "using" 语句中的巧妙方法,但无法计算出语法。
假设 class 是...
class Something : IDisposable
函数是...
void PopulateSomething(Something theObject)
我可以做到...
Something myObject = new Something();
PopulateSomethingObject(myObject);
x = myObject.SomeNumber;
myObject.Dispose();
或者我也可以这样做...
Something myObject = new Something();
using(myObject)
{
x = myObject.SomeNumber;
}
但以上都不好,因为处理后我可以愚蠢地写这样的东西
x = myObject.SomeNumber; // which will throw an exception
我想我可以做到...
using(Something myObject = new Something())
{
PopulateSomethingObject(myObject);
x = myObject.SomeNumber();
}
但我想相信类似下面的东西是可能的,但我无法弄清楚语法...
using (Something myObject => PopulateSomethingObject(myObject = new Something()))
{
x = myObject.SomeNumber();
}
我想这是一个理论问题,因为我在这里真的没有问题,但我很想知道这是否可能。即实例化对象并将其传递给“using(...){} 块声明中的方法。
问题出在 PopulateSomething
方法的签名上,它会阻止您在单个表达式中创建和使用 Something
对象。由于 PopulateSomething
的 return 类型是 void
,它必须用作语句,而不是表达式。
你最后编译的方法很不错:
using (Something myObject = new Something()) {
PopulateSomethingObject(myObject);
x = myObject.SomeNumber();
}
事实上,它类似于用于数据库连接的模式,当在 using
中创建的对象在使用前进行一些额外的配置时:
using (conn = factory.CreateConnection()) {
// Do more things to conn before its first use.
conn.ConnectionString = "...";
conn.Open();
... // Use conn here
}
如果您想避免在 using
中调用 PopulateSomethingObject
,请创建工厂方法 returning Something
,如下所示:
private static Something GetAndConfigure() {
Something res = new Something();
PopulateSomethingObject(res);
return res;
}
现在你可以写了
using (Something myObject = GetAndConfigure()) {
x = myObject.SomeNumber();
}
using(Something myObject = new Something())
{
PopulateSomethingObject(myObject);
x = myObject.SomeNumber();
}
这是 USING 块的正确用法。您在括号内创建实例。
如果您真的不想处置该对象,那么您一开始就不应该使用 USING。
以下是您可以执行的操作
private Something CreateAndPopulate()
{
var myObject = new Something();
PopulateSomethingObject(myObject);
return myObject;
}
然后像这样使用它:
using (var myObject = CreateAndPopulate())
{
x = myObject.SomeNumber();
}
更新1
另一种方法是为 Something
写一个扩展,比如
public static class SomethingExtension
{
public static Something Populate(this Something someObj, Action<Something> actionToPopulate)
{
actionToPopulate.Invoke(someObj);
return someObj;
}
}
然后在一行中使用它,例如:
using (var myObject = new Something().Populate(PopulateSomethingObject))
{
x = myObject.SomeNumber();
}
更新2
Fianlly,这样做的一种方法可能看起来很复杂
using (var myObject = new Func<Something>(() =>
{
var myNewObject = new Something();
PopulateSomethingObject(myNewObject);
return myNewObject;
}).Invoke())
{
//x = myObject.SomeNumber();
}
不,您应该只在 using
中放置对象。
在我看来,这个想法并不是很好。我看到代码的两部分 - 第一个路径创建对象,第二个 - 处理它。然后您尝试将第一部分与第二部分混合。我认为最后一个选项的可读性不如
using(Something myObject = new Something())
{
PopulateSomethingObject(myObject);
x = myObject.SomeNumber();
}
我正在使用实现 IDisposable 的外部 class 和填充该 class 实例的外部方法。
我正在寻找一种将一次性对象封装在 "using" 语句中的巧妙方法,但无法计算出语法。
假设 class 是...
class Something : IDisposable
函数是...
void PopulateSomething(Something theObject)
我可以做到...
Something myObject = new Something();
PopulateSomethingObject(myObject);
x = myObject.SomeNumber;
myObject.Dispose();
或者我也可以这样做...
Something myObject = new Something();
using(myObject)
{
x = myObject.SomeNumber;
}
但以上都不好,因为处理后我可以愚蠢地写这样的东西
x = myObject.SomeNumber; // which will throw an exception
我想我可以做到...
using(Something myObject = new Something())
{
PopulateSomethingObject(myObject);
x = myObject.SomeNumber();
}
但我想相信类似下面的东西是可能的,但我无法弄清楚语法...
using (Something myObject => PopulateSomethingObject(myObject = new Something()))
{
x = myObject.SomeNumber();
}
我想这是一个理论问题,因为我在这里真的没有问题,但我很想知道这是否可能。即实例化对象并将其传递给“using(...){} 块声明中的方法。
问题出在 PopulateSomething
方法的签名上,它会阻止您在单个表达式中创建和使用 Something
对象。由于 PopulateSomething
的 return 类型是 void
,它必须用作语句,而不是表达式。
你最后编译的方法很不错:
using (Something myObject = new Something()) {
PopulateSomethingObject(myObject);
x = myObject.SomeNumber();
}
事实上,它类似于用于数据库连接的模式,当在 using
中创建的对象在使用前进行一些额外的配置时:
using (conn = factory.CreateConnection()) {
// Do more things to conn before its first use.
conn.ConnectionString = "...";
conn.Open();
... // Use conn here
}
如果您想避免在 using
中调用 PopulateSomethingObject
,请创建工厂方法 returning Something
,如下所示:
private static Something GetAndConfigure() {
Something res = new Something();
PopulateSomethingObject(res);
return res;
}
现在你可以写了
using (Something myObject = GetAndConfigure()) {
x = myObject.SomeNumber();
}
using(Something myObject = new Something())
{
PopulateSomethingObject(myObject);
x = myObject.SomeNumber();
}
这是 USING 块的正确用法。您在括号内创建实例。
如果您真的不想处置该对象,那么您一开始就不应该使用 USING。
以下是您可以执行的操作
private Something CreateAndPopulate()
{
var myObject = new Something();
PopulateSomethingObject(myObject);
return myObject;
}
然后像这样使用它:
using (var myObject = CreateAndPopulate())
{
x = myObject.SomeNumber();
}
更新1
另一种方法是为 Something
写一个扩展,比如
public static class SomethingExtension
{
public static Something Populate(this Something someObj, Action<Something> actionToPopulate)
{
actionToPopulate.Invoke(someObj);
return someObj;
}
}
然后在一行中使用它,例如:
using (var myObject = new Something().Populate(PopulateSomethingObject))
{
x = myObject.SomeNumber();
}
更新2 Fianlly,这样做的一种方法可能看起来很复杂
using (var myObject = new Func<Something>(() =>
{
var myNewObject = new Something();
PopulateSomethingObject(myNewObject);
return myNewObject;
}).Invoke())
{
//x = myObject.SomeNumber();
}
不,您应该只在 using
中放置对象。
在我看来,这个想法并不是很好。我看到代码的两部分 - 第一个路径创建对象,第二个 - 处理它。然后您尝试将第一部分与第二部分混合。我认为最后一个选项的可读性不如
using(Something myObject = new Something())
{
PopulateSomethingObject(myObject);
x = myObject.SomeNumber();
}