简体   繁体   English

调用类方法而不是扩展方法

[英]Call Class Method Rather Than Extension Method

I'm working with the MongoDB C# Driver and NSubstitute. 我正在使用MongoDB C#驱动程序和NSubstitute。 I need to mock the FindAsync method on the IMongoCollection class. 我需要在IMongoCollection类上模拟FindAsync方法。 The problem is that there is a IMongoCollectionExtension class with the exact same signature . 问题是存在一个具有完全相同签名的IMongoCollectionExtension类。 When I attempt to mock the FindAsync method it calls the extension method which throws an exception due to the Ensure.IsNotNull call. 当我尝试模拟FindAsync方法时,它会调用扩展方法,该扩展方法会由于“ Secure.IsNotNull”调用而引发异常。

Is there a way to ensure the class method is called rather than the extension method? 有没有一种方法可以确保调用类方法而不是扩展方法? It's not working that way now. 现在还不行。 They are even in the same namespace. 它们甚至位于同一名称空间中。

Example of how I'm trying to call it via my test. 我试图通过测试调用它的示例。

        _collection = Substitute.For<IMongoCollection<DirectoryObject>>();
        _database.GetCollection<DirectoryObject>(Constants.DirectoryObjectCollection).Returns(_collection);
        _collection.FindAsync(Arg.Any<FilterDefinition<DirectoryObject>>(), null, default(CancellationToken)).Returns(cursor);

Method Signature: 方法签名:

Task<IAsyncCursor<TProjection>> FindAsync<TProjection>(FilterDefinition<TDocument> filter, FindOptions<TDocument, TProjection> options = null, CancellationToken cancellationToken = default(CancellationToken));

Extension Method Signature: 扩展方法签名:

public static Task<IAsyncCursor<TDocument>> FindAsync<TDocument>(this IMongoCollection<TDocument> collection, FilterDefinition<TDocument> filter, FindOptions<TDocument, TDocument> options = null, CancellationToken cancellationToken = default(CancellationToken))

Screenshot of the IntelliSense suggesting I'm calling the extension method. IntelliSense的屏幕快照,提示我正在调用扩展方法。

在此处输入图片说明

EDIT: 编辑:

Changing the mocked method call to this fixes the issue. 将模拟方法调用更改为此可以解决此问题。 The signatures aren't exactly the same. 签名并不完全相同。 The extension doesn't have a different projection and document type. 该扩展名没有其他投影和文档类型。

        _collection.FindAsync<DirectoryObject>(Arg.Any<FilterDefinition<DirectoryObject>>(), null, default(CancellationToken)).Returns(cursor);

For reference if anyone else thinks they have this problem, you don't! 如果其他人认为他们有此问题,请参考,您可以! On a naming clash between an instance method and an extension method, it is the instance method is called. 在实例方法和扩展方法之间的命名冲突时,将调用实例方法。

If you do need preferentially select which method is called, you actually have the reverse problem which is to call the extension method directly using it's declaring class. 如果确实需要优先选择调用哪个方法,则实际上存在一个相反的问题,即使用其声明类直接调用扩展方法。

eg with a name clash like this: 例如,名称冲突如下:

public static class ObjectExt 
{ 
    public static string ToString(this object o) => ""; 
}

you can disambiguate as: 您可以消除歧义为:

instance.ToString(); // call the instance method

ObjectExt.ToString(instance); // call the extension method

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM