避免通用参数

发布于 2024-11-15 05:48:19 字数 416 浏览 3 评论 0原文

我有以下扩展方法,它断言属性 (Id) 包含指定的属性 (TV):

public static void ShouldHave<T, TV, TT>(this T obj, Expression<Func<T, TT>> exp) {...}

该方法可以这样调用:

MyDto myDto = new MyDto();
myDto.ShouldHave<MyDto, RequiredAttribute, int>(x => x.Id);

编译得很好。我想知道是否可以从方法签名中删除 T 和 TT。 T 因为 ShouldHave 是在 T 上调用的,所以不需要显式指定它。 TT 是表达式 (x.Id) 中引用的属性的类型。

I have the following extension method which asserts that a property (Id) contains a specified attribute (TV):

public static void ShouldHave<T, TV, TT>(this T obj, Expression<Func<T, TT>> exp) {...}

The method can be called like this:

MyDto myDto = new MyDto();
myDto.ShouldHave<MyDto, RequiredAttribute, int>(x => x.Id);

Compiles just fine. I was wondering if it is possible to remove T and TT from the method signature. T because ShouldHave is called on T why it shouldn't be necessary to specify it explicitly. And TT is the type of the property referenced in the expression (x.Id).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

瘫痪情歌 2024-11-22 05:48:19

编译如下:

public static void ShouldHave<T, TT>(this T obj, Expression<Func<T, TT>> exp)
{...}

MyDto myDto = new MyDto();
myDto.ShouldHave(x => x.Id);

这省略了 TV 类型参数,这就是您需要在调用站点显式指定通用参数的原因。如果你需要这个论点,那么你就不走运了。

The following compiles:

public static void ShouldHave<T, TT>(this T obj, Expression<Func<T, TT>> exp)
{...}

MyDto myDto = new MyDto();
myDto.ShouldHave(x => x.Id);

This omits the TV type argument, which is the reason for your need to explicitly specify the generic arguments at the call site. If you need this argument then you’re out of luck.

宫墨修音 2024-11-22 05:48:19

仅当方法调用中没有指定泛型参数时,类型参数的自动推断才有效。即,这:

myDto.ShouldHave<, RequiredAttribute, >(x => x.Id);

不是有效的语法。你可以选择“全有或全无”。

因此,如果您想推断 TTT,您需要以其他方式传递 TV 中当前包含的信息。例如,一种选择是将属性的类型作为参数传递:(

public static void ShouldHave<T, TT>(this T obj, 
                                     Expression<Func<T, TT>> exp, 
                                     Type attribute) {...}

显然,这需要更改 ShouldHave 的实现)。

然后你应该能够像这样调用该方法:

MyDto myDto = new MyDto();
myDto.ShouldHave(x => x.Id, typeof(RequiredAttribute));

Automatic inference of type arguments only works if no generic arguments are specified in the method call. I.e., this:

myDto.ShouldHave<, RequiredAttribute, >(x => x.Id);

is not valid syntax. You can either have "all or nothing".

Thus, if you want to infer T and TT, you need to pass the information currently contained in TV in some other way. For example, one option would be to pass the type of the attribute as a parameter:

public static void ShouldHave<T, TT>(this T obj, 
                                     Expression<Func<T, TT>> exp, 
                                     Type attribute) {...}

(Obviously, this will require changes in your implementation of ShouldHave).

Then you should be able to call the method like this:

MyDto myDto = new MyDto();
myDto.ShouldHave(x => x.Id, typeof(RequiredAttribute));
你是我的挚爱i 2024-11-22 05:48:19

试试这个:

public static void ShouldHave<TV>(this object obj, Expression<Func<object, object>> exp) {...}

您应该发现 exp 现在由被强制转换为对象的真实表达式组成。在您的方法中,按如下方式剥离强制转换:

Expression realExp = ((UnaryExpression) exp).Operand;

然后您可以开始分析表达式。不过,与原始方法相比,您必须进行更多的运行时测试和安全检查。

Try this:

public static void ShouldHave<TV>(this object obj, Expression<Func<object, object>> exp) {...}

You should find that exp now consists of the real expression surrounded by a cast to object. Inside your method, strip off the cast as follows:

Expression realExp = ((UnaryExpression) exp).Operand;

Then you can start analysing the expression. You will have to do more runtime tests and safety checks than your original method though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文