Когда я изучал язык Go, мне очень понравилась идея с приведением к интерфейсам по сигнатурам методов (остальная часть системы типов мне не понравилась, слишком примитивная). Это ведь статическая утиная типизация! По научному: структурная типизация.
Если вдуматься, у такого подхода куча недостатков: начиная со сложности реализации и заканчивая нарушением принципа подстановки Лисков. Ведь если у класса есть метод с нужной сигнатурой (включая название), это совсем не значит, что этот метод делает то, что ожидается.
Поэтому в мейнстрим языках, в том числе в C#, структурная типизация не поддерживается. Казалось бы на этом и сказке конец. Но недавно я осознал что в проекте, которым я сейчас занимаюсь, структурная типизация применяется. Подробности под катом.
В проекте метод применяется для работы с геттерами/сеттерами. Конечно его можно использовать и для обычных методов, но вряд ли это даст что-то хорошее.
Итак. Представьте, что у вас есть набор классов, у которых много одинаковых свойств (название и тип).
И ещё больше классов, которым для работы нужны данные из этих свойств. Например: есть класс DataItem с автосвойствами A, B и C. И класс Calculator, которому требуется значение свойства A, чтобы на его основе что-то вычислить и занести в B. А про C ему знать не надо. Также ему не надо знать и про класс DataItem, т.к. он может использоваться и с другими классами у которых есть A и B.
Как это реализовать? Заранее объявить для каждого, из таких свойств интерфейс, и каждый класс с такими свойствами пометить, как реализующий соответствующие интерфейсы. А методы классов потребителей объявлять generic-ами.
Реализация:
interface PropertyA{
int A {get; set;}
}
class DataItem: PropertyA, PropertyB, PropertyC{
public int A {get; set;}
public bool B {get; set;}
public string C {get; set;}
}
...
void Calculate<T>(T data) where T: PropertyA, PropertyB{
data.B = data.A > 0;
}
Всё просто: указывая ограничения generic параметра можно собрать подходящий набор полей, и объект любого класс их реализующий передать в такой метод без всяких приведений.
Сложнее понять зачем это может пригодиться, и не является ли ситуация, когда подобная техника нужна, ещё одним запахом кода.
Автор: Vestild