#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.
, что это не добавляет ничего, кроме отвлекающего беспорядка.