#c_sharp #ссылки #интерфейс #методы
Добрый день, очень сильно плаваю в теме про обобщенные интерфейсы, методы. Был бы весьма благодарен за подсказку, либо за ссылки, в каком направлении следует копать, читать. Теорию прочитал с сайта professorweb.ru про интерфейсы, обобщение. Теория теорией, что то понял, чего то нет, но на практике все равно не могу реализовать следующую задачку. К примеру, имеется код: DataPerson dataPerson; IEnumerableperson = dataPerson. >Get(); // как я понял, метод Get() должен в person записать значение ссылочного типа // на реализующий интерфейс типа Person? Не представляю как реализовать это. // В плане непонятны мне следующие вопросы: // 1. Где следует реализовать этот интерфейс? // 2. Не понимаю про двойное обобщение вида >, // а именно каким образом это указать в методе Get()? // 3. Не понимаю как вернуть интерфейс через метод. Класс Person: class Person { public string FirstName { get; set; } public string LastName { get; set; } public Person(string fName, string lName) { FirstName = fName; LastName = lName; } } Класс DataPerson: class DataPerson { // как я примерно представляю объявление функции Get() public IEnumerable Get () where T : IEnumerable { // как реализовать, к сожалению не представляю } } Как собственно реализовать метод Get() в классе DataPerson?
Ответы
Ответ 1
Ваш метод скорее всего должен быть объявлен как class DataPerson { public IEnumerableGet () where T : new() { } } т.к. реально у него всего один тип-параметр - тип выбираемых объектов. и использоваться как IEnumerable person = dataPerson Get(); Реализовать его можно двумя способами: Действительно создать что-то, что реализует интерфейс IEnumerable. Например, массив или список. Заполнить его и вернуть из метода: class DataPerson { public IEnumerable Get () where T : new() { var query = buildSomeQueryFor(typeof(T)); // построить запрос для выбора объектов типа T DataRow[] dataRows = selectSomeRowsFromDB(query); // var result = new List (); foreach (var row in dataRows) { result.Add(MapDataRowTo (row)); } return result; } private MapDataRowTo (DataRow row) where T : new () { var newObject = new T(); // map values from row to newObject // return return newObject; } } Второй способо - использовать ключевое слово yield: class DataPerson { public IEnumerable Get () where T : new() { var query = buildSomeQueryFor(typeof(T)); // построить запрос для выбора объектов типа T DataRow[] dataRows = selectSomeRowsFromDB(query); // foreach (var row in dataRows) { yield return MapDataRowTo (row); } } private MapDataRowTo (DataRow row) where T : new () { var newObject = new T(); // map values from row to newObject // return return newObject; } } Использование yield завернет ваш метов в обертку-IEnumerable, которая будет возвращать элементы по мере обращения к ним из вызывающего кода. Т.е. выполнение метода Get будет происходить кусками, от одного вызова yield к следующему. В MSDN есть достаточно подробная документация по этой фиче языка. Ответ 2
Как собственно реализовать метод Get() в классе DataPerson? class DataPerson { public IEnumerableGet() { return new List () { new Person(), new Person() }; } // или так public IEnumerable Get() { return new[] { new Person(), new Person() }; } }
Комментариев нет:
Отправить комментарий