gpt4 book ai didi

c# - 如何在 C# 中编写通用扩展方法来转换类型

转载 作者:行者123 更新时间:2023-11-30 19:56:06 27 4
gpt4 key购买 nike

我正在编写一个静态保护类/api 来验证发送到方法的参数。

到目前为止的代码如下:

public static class Guard
{
public static GuardArgument<T> Ensure<T>(T value, string argumentName)
{
return new GuardArgument<T>(value, argumentName);
}

public static T Value<T>(this GuardArgument<T> guardArgument)
{
return guardArgument.Value;
}

// Example extension method
public static GuardArgument<T> IsNotNull<T>(this GuardArgument<T> guardArgument, string errorMessage)
{
if (guardArgument.Value == null)
{
throw new ArgumentNullException(guardArgument.Name, errorMessage);
}

return guardArgument;
}
}

可以这样使用:

public void Test(IFoo foo) {

Guard.Ensure(foo, "foo").IsNotNull();
}

现在的情况要求我需要从提供的接口(interface)转换为具体类型。不要问为什么,我就是需要!

我想向 GuardArgument 添加一个 As 扩展方法来执行此操作,例如:

public static GuardArgument<TOut> As<TOut, TIn>(this GuardArgument<TIn> guardArgument, Type type)
where TOut : class
{
// Check cast is OK, otherwise throw exception

return new GuardArgument<TOut>(guardArgument.Value as TOut, guardArgument.Name);
}

虽然我不太喜欢语法。我希望能够按如下方式使用该类:

 Foo foo = Guard.Ensure(foo, "foo")
.As(typeof(Foo))
.IsNotNull()
.Value();

虽然我不确定如何编写扩展方法来允许这种语法。我意识到我可以将现有的流畅 API 用作:

 Foo foo = Guard.Ensure(foo as Foo, "foo")
.IsNotNull()
.Value();

但从可读性的角度来看,我不喜欢这样。

最佳答案

你可以得到这样的语法:

Foo foo = Guard.Ensure(foo, "foo")
.As<Foo>()
.IsNotNull()
.Value();

诀窍是放弃 TIn类型参数。它未在 As() 中使用方法并在由于 TOut 而无法使用类型推断时膨胀 API .能够在没有得到 As() 的情况下做到这一点建议在所有类型上你必须为你的 GuardArgument<> 实现一个新的非通用接口(interface)类:

interface IGuardArgument 
{
object Value { get; }
strign Name { get; }
}

public class GuardArgument<T> : IGuardArgument
{
// Explicit implementation to hide this property from
// intellisense.
object IGuardArgument.Value { get { return Value; }

// Rest of class here, including public properties Value and Name.
}

现在你可以写As()只有一个通用参数的方法:

public static GuardArgument<TOut> As<TOut>(this IGuardArgument guardArgument)
where TOut : class
{
// Check cast is OK, otherwise throw exception

return new GuardArgument<TOut>(guardArgument.Value as TOut, guardArgument.Name);
}

关于c# - 如何在 C# 中编写通用扩展方法来转换类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34871385/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com