C# 中的链接扩展方法
是否可以创建一个返回调用扩展方法的实例的扩展方法?
我希望有一个扩展方法,用于从 ICollection
继承并返回对象的任何内容。很像 jQuery 总是返回 jquery 对象。
public static object AddItem<T>(this ICollection<T> collection, T itemToAdd)
{
collection.Add(itemToAdd);
return collection;
{
我想象类似上面的东西,但我不确定如何返回到“this”对象类型的父级以使用类似这样的东西:
List<int> myInts = new List<int>().AddItem(5);
编辑:只是想清楚我希望有一个通用约束解决方案。
Is it possible to create an extension method that returns the instance that is invoking the extension method?
I would like to have an extension method for anything that inherits from ICollection<T>
, returns the object. Much like how jQuery always returns the jquery object.
public static object AddItem<T>(this ICollection<T> collection, T itemToAdd)
{
collection.Add(itemToAdd);
return collection;
{
I imagine something like above, but I am not sure how to get back to the parent to the "this" object type for use of something like this:
List<int> myInts = new List<int>().AddItem(5);
EDIT: Just wanted to be clear that i was hoping for a single generic constraint solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果需要返回特定类型,可以使用通用约束:
我对此进行了测试,它在 VS2010 中有效。
更新(关于 jQuery):
jQuery 链接工作得很好,因为 JavaScript 使用动态类型。 C# 4.0 支持
动态
,因此您可以这样做:但是,我确实推荐通用约束版本,因为它更类型安全、更高效,并且允许对返回类型进行 IntelliSense。在更复杂的场景中,通用约束并不总是能够表达您的需求;在这些情况下,可以使用
dynamic
(尽管它不会绑定到其他扩展方法,因此它不能很好地与链接配合使用)。If you need to return the specific type, you can use a generic constraint:
I tested this and it works in VS2010.
Update (regarding jQuery):
jQuery chaining works very well because JavaScript uses dynamic typing. C# 4.0 supports
dynamic
, so you can do this:However, I do recommend the generic constraint version, since it is more type-safe, more efficient, and allows IntelliSense on the returned type. In more complex scenarios, generic constraints aren't always capable of expressing what you need; in those cases,
dynamic
can be used (though it won't bind to additional extension methods, so it doesn't work well with chaining).虽然我没有打开 VS 来尝试此操作,但以下内容应该可以工作:
While I don't have VS open to try this, something along these lines should work:
您似乎有两个相互冲突的目标,这取决于您希望扩展方法返回什么:
从您的示例用法中引用,此处引用:
你看起来像是要归还藏品。无论如何,如果没有强制转换,该分配仍然无法工作,因为您的扩展方法需要具有 ICollection 的返回类型,如下所示:
这将允许您执行此操作:
现在,如果您宁愿返回以下对象添加后,您仍然不应该有
object
返回类型。您应该利用泛型类型参数,并返回T
,如下所示:但是,如果您要返回添加的项目,则将无法像这样链接:
,因为
AddItem(5)
的返回类型不是 ICollection,而是T
(在本例中为int
) 。不过,您仍然可以链接,只是从添加的值开始,如下所示:似乎第一个场景更有用(返回集合),因为它确实允许您从初始赋值语句开始链接。下面是一个更大的示例:
或者,如果您不想进行强制转换,则可以对返回的 ICollection 调用
ToList()
:You seem to have 2 conflicting goals, and it comes down to what do you want your extension method to return:
From your example usage, quoted here:
You make it look like you want to return the collection. In any case, that assignment still won't work without a cast, since your extension method would need to have a return type of ICollection, like this:
That would allow you to do this:
Now if you'd rather return the object that was added, you still shouldn't have a return type of
object
. You should take advantage of your generic type parameter, and returnT
, like this:However, if you're returning the item that was added, you won't be able to chain like this:
, since the return type of
AddItem(5)
is not ICollection, but it'sT
(int
, in this case). You can still chain though, just off of the value added, like this:It seems like the first scenario is more useful (returning the collection), because it does allow you chain, right off of the initial assignment statement. Here's a larger example of that:
Or, if you don't want to cast, you can call
ToList()
on the ICollection that comes back:在这种情况下,您就不走运了,因为返回类型转换可以是协变的,但不是逆变的(即您不能从
ICollection
隐式转换为List
),所以如果没有通用返回类型,这是无法完成的。无论如何指定 2 个类型参数有什么问题吗?它们可以通过您提供给函数的参数来推断,因此您甚至不会在调用代码中真正注意到它们。
In this case you're out of luck because return type conversions can be covariant, but not contravariant (i.e. you cannot implicitly convert from
ICollection<T>
toList<T>
), so without a generic return type this cannot be done.What's wrong with specifying 2 type parameters anyway? They can be inferred by the arguments you provide to the function so you won't even really notice them in your calling code.
只需返回
ICollection
而不是object
,一切都会按照您的预期工作。Just return
ICollection<T>
instead ofobject
and everything should work like you intended it.