所以我创建了一个提供程序(实际上是其中的一些),我意识到我的一些逻辑中有一些模式。它正在重复,我认为如果我可以创建这个扩展方法,我可以删除大量代码:D
所以,基本上发生的事情是这样的:
// Get our item to be deleted
var model = await this._service.GetAsync(id);
// If we have nothing, throw an error
if (model == null)
throw new HttpException(404, string.Format(Resources.GenericNotFound, "List item"));
现在,我在很多地方都这样做,不只是为了删除,而是为了更新。 我想创建一个扩展方法,允许我做这样的事情:
// Get our item to be deleted
var model = await this._service.GetAsync(id).ThowIfNull("List item");
我还需要它来处理任何返回类型。因此,在这种情况下,它可能是帐户,但是会有一个提供商也有此代码返回订单,但我需要扩展方法才能同时使用。< / p>
我认为这里的挑战是异步位,但我可能错了!
有人知道是否有可能吗?
答案 0 :(得分:5)
避免异步等待部分的一种可能性是使扩展方法适用于Task
public static T ThrowIfNull<T>(this T obj, string message) where T : class
{
if (obj == null)
throw new HttpException(404, string.Format(Resources.GenericNotFound, message));
return obj;
}
我将扩展方法设为通用,因为我不知道model
是什么类型。然后你可以像这样使用它。
var model = (await this._service.GetAsync(id)).ThrowIfNull("List item");
将await
放在括号中,确保它等待任务并在将结果传递给扩展方法之前将其解包。
另一种选择是使扩展方法适用于Task<T>
public static async Task<T> ThrowIfNullAsync<T>(this Task<T> task, string message)
where T : class
{
var obj = await task;
if (obj == null)
throw new HttpException(404, string.Format(Resources.GenericNotFound, message));
return obj;
}
你不需要括号。
var model = await this._service.GetAsync(id).ThrowIfNullAsync("List item");
但这意味着异常现在包含在任务中,根据您使用此方法的方式,这可能是也可能不合适。
答案 1 :(得分:3)
您可以在任何T
上定义扩展方法:
public static class GenericExtensions
{
public static T ThrowIfNull<T>(this T obj, string message)
{
if (obj == null)
throw new HttpException(404,
string.Format(Resources.GenericNotFound, message));
return obj;
}
}
如果您不关心返回类型,可以使用object
,但这会导致价值类型的装箱(不确定我是否真的使用过这个):
public static class ObjectExtensions
{
public static void ThrowIfNull(this object obj, string message)
{
if (obj == null) throw new ArgumentNullException(message);
}
}
然后在任何返回类型上使用它:
async Task SomeAsyncMethod()
{
(await Foo()).ThrowIfNull("hello");
}
public Task<int> Foo()
{
return Task.FromResult(0);
}
答案 2 :(得分:0)
我创建了一个这样的方法:
/// <summary>
/// Throws a 404 Not found exception
/// </summary>
/// <param name="model">The model to check</param>
/// <param name="name">The name to display in the message</param>
/// <returns></returns>
public static T ThrowIfNotFound<T>(this T model, string name)
{
// If we have nothing, throw an error
if (model == null)
throw new HttpException(404, string.Format(Resources.GenericNotFound, name));
// Return our model
return model;
}