jan*_*jan 9 c# garbage-collection dispose destructor
我在C#中有一个"Status"类,使用如下:
Status MyFunction()
{
if(...) // something bad
return new Status(false, "Something went wrong")
else
return new Status(true, "OK");
}
Run Code Online (Sandbox Code Playgroud)
你明白了.MyFunction的所有调用者都应检查返回的状态:
Status myStatus = MyFunction();
if ( ! myStatus.IsOK() )
// handle it, show a message,...
Run Code Online (Sandbox Code Playgroud)
然而,懒惰的呼叫者可以忽略状态.
MyFunction(); // call function and ignore returned Status
Run Code Online (Sandbox Code Playgroud)
要么
{
Status myStatus = MyFunction();
} // lose all references to myStatus, without calling IsOK() on it
Run Code Online (Sandbox Code Playgroud)
有可能使这不可能吗?例如抛出异常
一般来说:是否可以编写一个C#类,您必须在其上调用某个函数?
在Status类的C++版本中,我可以在析构函数中对某些私有bool bIsChecked编写测试,并在有人不检查此实例时响铃.
C#中的等价选项是什么?我在某处读到"你不想在你的C#类中使用析构函数"
IDisposable接口的Dispose方法是一个选项吗?
在这种情况下,没有非托管资源可供免费使用.此外,GC 不会确定何时处置该对象.当它最终被处置时,是否仍然可以知道忽略该特定Status实例的位置和时间?"using"关键字确实有帮助,但同样,懒惰的调用者不需要它.
Ian*_*son 10
我知道这不会直接回答你的问题,但是如果你的功能中出现"出问题"(意外情况),我认为你应该抛出异常而不是使用状态返回码.
然后将其留给调用者来捕获并处理此异常(如果可以),或者如果调用者无法处理该情况则允许它传播.
如果这是合适的,抛出的异常可以是自定义类型.
对于预期的替代结果,我同意@Jon Limjap的建议.我喜欢bool返回类型,并在方法名称前加上"Try",a la:
bool TryMyFunction(out Status status)
{
}
Run Code Online (Sandbox Code Playgroud)
如果你真的想要求用户检索MyFunction的结果,你可能想要取消它而使用out或ref变量,例如,
void MyFunction(out Status status)
{
}
Run Code Online (Sandbox Code Playgroud)
它可能看起来很丑陋,但至少它确保将一个变量传递给函数,该函数将获取您需要它获取的结果.
@Ian,
异常的问题在于,如果某些事情经常发生,您可能会为异常花费太多系统资源.真正的异常应该用于异常错误,而不是完全预期的消息.
我相当确定你无法从方法的返回值中获得你想要的效果。C# 无法完成 C++ 可以做的一些事情。然而,获得类似效果的一种有点丑陋的方法如下:
using System;
public class Example
{
public class Toy
{
private bool inCupboard = false;
public void Play() { Console.WriteLine("Playing."); }
public void PutAway() { inCupboard = true; }
public bool IsInCupboard { get { return inCupboard; } }
}
public delegate void ToyUseCallback(Toy toy);
public class Parent
{
public static void RequestToy(ToyUseCallback callback)
{
Toy toy = new Toy();
callback(toy);
if (!toy.IsInCupboard)
{
throw new Exception("You didn't put your toy in the cupboard!");
}
}
}
public class Child
{
public static void Play()
{
Parent.RequestToy(delegate(Toy toy)
{
toy.Play();
// Oops! Forgot to put the toy away!
});
}
}
public static void Main()
{
Child.Play();
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
在这个非常简单的示例中,您可以通过调用 Parent.RequestToy并向其传递一个 delegate 来获取 Toy 的实例。该方法不返回玩具,而是立即使用玩具调用委托,该委托必须在返回之前调用 PutAway,否则 RequestToy 方法将引发异常。我没有宣称使用这种技术是否明智——事实上,在所有“出了问题”的例子中,例外几乎肯定是更好的选择——但我认为它会尽可能接近你最初的要求。
归档时间: |
|
查看次数: |
503 次 |
最近记录: |