Лучший способ преобразовать IEnumerable <T> в T []

Я пытаюсь с тем же кодом. Я не получаю эту ошибку. Spring boot version: 1.5.0.RELEASE

Вместо POST я попробовал использовать GET API с тем же шаблоном URL. / в конце пути не имеет значения.

@Component
public class CoreServiceClient {
    private RestTemplate restTemplate;

    private static final Logger LOGGER = LoggerFactory.getLogger(CoreServiceClient.class);
    private static final String root = "http://localhost:8080/test/api/";

    public CoreServiceClient(RestTemplateBuilder restTemplateBuilder) {
        restTemplate = restTemplateBuilder.rootUri(root).build();
    }


    public void updateState(String id) {

        try {
            ResponseEntity<String> response =
                    restTemplate.exchange("/food/{id}/state", HttpMethod.GET, null, String.class, id);
            LOGGER.info("Resp: {}", response.getStatusCode());
            LOGGER.info("Resp: {}", response.getBody());
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }


    }
}

Я добавил фиктивный контроллер с тем же путем:

@RestController
@RequestMapping("/test/api")
public class FooController {

    @GetMapping("/food/{id}/state")
    public ResponseEntity<String> fooState(@PathVariable String id) {
        return new ResponseEntity<String>("EATING", HttpStatus.OK);
    }
}

Для тестирования я добавил еще один контроллер:

@RestController
@RequestMapping("/client")
public class CoreServiceClientController {

    @Autowired
    private CoreServiceClient client;

    @GetMapping
    public ResponseEntity<String> goGet() {
        client.updateState("1001");
        return new ResponseEntity<>("HELLO", HttpStatus.OK);
    }
}

У меня все отлично работает. [1110 ]

Журнал:

2019-01-15 23:23:19.870  INFO 22570 --- [nio-8080-exec-1] com.example.demo001.CoreServiceClient    : Resp: 200
2019-01-15 23:23:19.871  INFO 22570 --- [nio-8080-exec-1] com.example.demo001.CoreServiceClient    : Resp: EATING
8
задан casperOne 30 May 2012 в 14:14
поделиться

3 ответа

.NET 3.0 и после:

Звоните ToArray дополнительный метод на IEnumerable<T>, это делает почти то же как ниже, выполняя сниффинг типа и некоторую другую оптимизацию.

.NET 2.0 и прежде:

Вообще говоря, использование a List<T> который будет инициализирован с IEnumerable<T> и затем вызов ToArray вероятно, самый легкий способ сделать это.

Конструктор для List<T> проверит IEnumerable<T> видеть, реализует ли это ICollection<T> заставить количество объектов правильно инициализировать способность списка. В противном случае это расширится как нормальное.

Конечно, Вы могли бы закончить тем, что создали много List<T> экземпляры только в целях преобразования IEnumerable<T> кому: T[]. С этой целью можно записать собственный метод, но Вы действительно просто копировали бы код, который существует в List<T> уже.

14
ответ дан 5 December 2019 в 08:54
поделиться

При выполнении небольшого Отражателя.NET, на который это похоже, метод расширения Linq ToArray в основном делает то же самое как передачу IEnumerable через Список <>. Буферный класс является внутренним, но поведение кажется очень похожим на Список <>.

public static TSource[] ToArray<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    Buffer<TSource> buffer = new Buffer<TSource>(source);
    return buffer.ToArray();
}
5
ответ дан 5 December 2019 в 08:54
поделиться

Если нет никакого способа определить длину массива, то это - лучший способ.

Нет ничего в IEnumerable, который позволит Вам определить длину, но возможно Ваш код имеет способ узнать иначе. Если так, используйте это для построения массива.

0
ответ дан 5 December 2019 в 08:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: