Функции расширения импорта, т. е. они могут быть вызваны как функции-члены?

#c# #extension-methods

Вопрос:

Допустим, я хочу упростить тестирование, сократив дублирование кода и централизовав создание макетов.

Так что все мои тесты в конечном итоге продлятся

 public abstract class UnitTestWithGameObjects
{
    private readonly List<GameObject> _createdGameObjects = new List<GameObject>();

    public void DestroyTestGameObjects()
    {
        _createdGameObjects.ForEach(Object.DestroyImmediate);
        _createdGameObjects.Clear();
    }
    
    public GameObject NewGameObject()
    {
        return new GameObject()
            .Also(_createdGameObjects.Add);
    }
}
 

Затем я добавляю функции расширения в этот класс, которые создают насмешки, например

 public static class TestableTowerCollection
{
    public static ITowerCollection TestTowerCollection(
        this UnitTestWithGameObjects unitTest,
        Properties properties,
        IArCameraManagerWrapper arCameraManagerWrapper = null,
        Vector3? cameraPosition = null,
        IArSessionOriginWrapper arSessionOriginWrapper = null
    )
    {
        IArCameraManagerWrapper cameraManagerWrapper = arCameraManagerWrapper
                                                       ?? unitTest.MockCameraManagerWrapper(cameraPosition);

        IArSessionOriginWrapper sessionOriginWrapper = arSessionOriginWrapper
                                                       ?? unitTest.MockArSessionOriginWrapper();

        return new TowerCollection(properties, cameraManagerWrapper, sessionOriginWrapper);
    }
}
 

где MockCameraManagerWrapper и MockArSessionOriginWrapper снова включены функции расширения UnitTestWithGameObjects (в разных файлах, например, чтобы методы конструктора были содержательно объединены).

поэтому в своих тестах я могу затем

     public class MyTestUsingTowerCollection : UnitTestWithGameObjects
    {

        private Properties _properties;
        private ITowerCollection _towerCollection;

        [SetUp]
        public void SetUp()
        {
            _properties = new Properties();
            _towerCollection = this.TestTowerCollection(
                _properties,
                cameraPosition: new Vector3(4, 0, -100000)
            );

            ...
        }

        ....
    }
 

Но, как вы заметите, для этого требуется

 this.TestTowerCollection(...)
 

вызов, в то время как я бы предпочел иметь неявное this :

 TestTowerCollection(...)
 

как, например, Котлин позволяет (https://ideone.com/wVLEjT)

Можно ли — и если да, то как — импортировать функции расширения таким образом, чтобы это было возможно?

Комментарии:

1. Ты не можешь. Методы расширения должны вызываться для объекта. Если вы хотите вызвать их this , вам нужно добавить префикс this.

2. Добавление TestTowerCollection в UnitTestWithGameObjects вместо того, чтобы сделать его методом расширения?

3. Как вы думаете, почему это выглядит лучше? Для меня это удаляет контекст из кода.

4. @cly, очевидно, так как это превратило бы расширение в функцию-член. Однако это также сделало бы UnitTestWithGameObjects довольно большими, а функции-члены было бы трудно найти, поскольку все смешивается вместе без применимой структуры. Я лично предпочел бы, чтобы функции расширения были разделены «темой» для более быстрого поиска.

5. @DavidG Я просто чувствую this. , что это не добавляет ничего, кроме отвлекающего беспорядка.