Страницы

Поиск по вопросам

четверг, 13 февраля 2020 г.

Вернуть реализующийся интерфейс IEnumerable<T> через метод, C#

#c_sharp #ссылки #интерфейс #методы


Добрый день, очень сильно плаваю в теме про обобщенные интерфейсы, методы. Был бы
весьма благодарен за подсказку, либо за ссылки, в каком направлении следует копать,
читать. Теорию прочитал с сайта professorweb.ru про интерфейсы, обобщение. Теория теорией,
что то понял, чего то нет, но на практике все равно не могу реализовать следующую задачку.

К примеру, имеется код:

DataPerson dataPerson;
IEnumerable person = 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 IEnumerable Get() where T : new() { } } т.к. реально у него всего один тип-параметр - тип выбираемых объектов. и использоваться как IEnumerable person = dataPersonGet(); Реализовать его можно двумя способами: Действительно создать что-то, что реализует интерфейс 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 IEnumerable Get() { return new List() { new Person(), new Person() }; } // или так public IEnumerable Get() { return new[] { new Person(), new Person() }; } }

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

Отправить комментарий