No and Yes. DataAdapter has a fine implementation for filling the DataSet. And of course it's possible. It's like
Code:
DataTable t = new DataTable();
			IDataReader reader = FromSomeConnection();
			for (int i = 0; i < reader.FieldCount; i++) {
				DataColumn c = new DataColumn();
				// Do something with the column
				t.Columns.Add(c);
			}
			while (reader.Read()) {
				DataRow r = t.NewRow();
				for (int i = 0; i < reader.FieldCount; i++) {
					r[i] = reader[i];
				}
				t.Rows.Add(r);
			}
When working with reader, it's more readable if you have a strongly type objects like
Code:
List<Employee> e = new List<Employee>();
			IDataReader reader = FromSomeConnection();
			while (reader.Read()) {
				e.Add(new Employee(reader["last_name"].ToString(), reader["first_name"].ToString(), reader["middle_name"].ToString()));
			}
			
			// Do something with the list of employees.
This way we know what type of list we are manipulating.