Visual Studio 2010 «Добавить ссылку» копирует dll в каталог bin?

Я использую w7, 64bit и vs.net 2010.

Я добавляю ссылку на компонент, который находится в моем диалоговом окне «Добавить ссылки». Компонент является сторонним dll.

Исторически на w7 32bit он добавил бы строку в мой web.config (внутри тега сборки), ссылающуюся на эту dll, и не скопировал бы dll в каталог bin.

Однако на 64-битном w7 dll копируется в каталог bin, а web.config вообще не обновляется.

Почему dll копируется в каталог bin? спасибо

Решение: (Обновлено) Эти сообщения дали мне подсказки, в которых я нуждался.

VS.NET скопирует dll в каталог bin, если ваша система не может найти dll в GAC. Сборки в GAC (зарегистрированные на вашей рабочей станции) и могут быть найдены, просмотрев каталог C: \ Windows \ Assembly.

Компоненты, перечисленные в vs.net «добавить ссылки диалоговое окно», могут или не могут быть в GAC. Поскольку компонент указан в диалоговом окне «Добавить ссылки», это не значит, что он зарегистрирован на локальной рабочей станции. Я переместился в каталог компонентов и перетащил нужные DLL в каталог C: \ Windows \ Assembly. Я закрыл и снова открыл vs.net, перешел к тем же файлам и нажал «Добавить ссылку».

** Это добавило ссылку на сборку в мою сеть.

15
задан Derek Mahar 24 August 2010 в 14:36
поделиться

9 ответов

Вместо передачи типа списка, который вы хотите создать, почему бы просто не передать пустую коллекцию, которую вы хотите заполнить? Это дает пользователям вашего API гораздо больше гибкости, так как использование конструктора по умолчанию не всегда идеально. (например, может быть, мне нужен набор, в котором я предоставляю ожидаемое количество элементов, или мне нужен отсортированный список, в котором я предоставляю компаратор).

Кроме того, в качестве примечания, вы всегда должны программировать максимально общий интерфейс. В этом случае ваш ввод не должен быть чем-то более конкретным, чем Iterable, а ваш вывод — Collection.

Учитывая это, я бы написал метод таким образом --

  public static <T, C extends Collection<T>> C typesafeAdd(Iterable<?> from, C to, Class<T> listClass) {
    for (Object item: from) {
      to.add(listClass.cast(item));
    }
    return to;
  }

тогда код вызова выглядит так:

  public static void main(String[] args) {
    List<?> untypedStringList = LegacyApi.getStringList();
    List<String> typesafeStringList = typesafeAdd(untypedStringList, new ArrayList<String>(), String.class);
  }

2 комментария здесь:

  • Если вы действительно можете доверять LegacyApi (или тому, что предоставило вам нетипизированный список) только для возврата вам коллекции с ожидаемым типом в ней, тогда вы можете просто выполнить непроверенное приведение и подавить его. . Это должно быть локализовано до минимально возможного масштаба. то есть: создайте что-то вроде TypesafeLegacyApiWrapper, которое делегирует вызовы LegacyApi.
  • Эта сигнатура метода по-прежнему ломается, если у вас есть что-то более сложное. Например, если у вас есть List>, этот метод не работает.
8
ответ дан 1 December 2019 в 02:37
поделиться

Метод Class.newInstance() выбрасывает два проверяемых исключения IllegalAccessException и InstantiationException. Они должны быть либо пойманы, либо объявлены в сигнатуре метода.

Для справки, эти исключения возникают в различных ситуациях; например,

  • класс не определяет конструктор no-args
  • конструктор не виден
  • класс является абстрактным или интерфейсом
  • объект класса обозначает тип массива, примитивный тип или void "type".

Это фактически не связано с тем, что метод является общим, и связанными с этим проблемами типизации.

1
ответ дан 1 December 2019 в 02:37
поделиться

Чего вы хотите достичь? Такой код:

List l = new ArrayList();
l.add(new Integer(1));
List<Integer> li = l;

просто работает. Выдает предупреждение, но работает. Однако возможно, что в li у вас будут объекты, которые не являются экземплярами Integer . Если хочешь быть уверенным, используй google guava, как ответил ColinD.

0
ответ дан 1 December 2019 в 02:37
поделиться

Я не верю, что то, что вы пытаетесь сделать, возможно. Это из-за работы Generics:

Во время компиляции проверяются все входящие типы типизированного списка, и все исходящие объекты приводятся к типу списка - и с этого момента мы говорим о нетипизированном «списке». К сожалению, дженерики - это всего лишь синтаксический сахар.

0
ответ дан 1 December 2019 в 02:37
поделиться

Я бы использовал Guava и его метод Iterables.filter (Iterable, Class) вместе с фабричным методом из Lists ], например так:

List<?> original = ...;
List<String> typed = Lists.newArrayList(
   Iterables.filter(original, String.class));

Это фактически проверит каждый объект в исходном списке, и результирующий список будет содержать только те элементы, которые являются экземплярами данного типа ( String в данном случае) или подтипа. этого. Я действительно не думаю, что имеет смысл заставлять пользователей предоставлять Class для результирующего типа List и пытаться создать его экземпляр через отражение.

13
ответ дан 1 December 2019 в 02:37
поделиться

Опять гуава, но позволяет лучше контролировать преобразование, если оно сложнее, чем приведение типов или еще много чего.

public List<L> convert(List<T> list) {
    return Lists.transform(list,new Function<T,L>() {

        public Object apply(T from) {

            L magic = (L)from;

            /* magic here */

            return magic;
        }});
}
3
ответ дан 1 December 2019 в 02:37
поделиться

У вас проблема во время выполнения, поэтому она не должна зависеть от универсальных шаблонов. Во время выполнения все в любом случае «является объектом». Если вы не можете создать экземпляр listClass , тогда вы действительно передаете реализацию java.util.List , которая не предлагает (общедоступный) пустой конструктор.

Итак, решение вашей проблемы находится вне этого метода. Вызов его типа

 List<String> result = typedList(untypedList, String.class, ArrayList.class);

не должен приводить к ошибке времени выполнения.


Теперь мое затмение близко. Следующий код компилируется и без предупреждений и должен соответствовать вашему требованию: преобразовать из нетипизированного списка в типизированный список.

public static <T> List<T> typedList(List<?> untypedList, Class<T> itemClass) {
  List<T> list = new ArrayList<T>();
  for (Object item : untypedList) {
    list.add(itemClass.cast(item));  // TODO - handle ClassCastExpception
  }
  return list;
}
2
ответ дан 1 December 2019 в 02:37
поделиться

Если вы не хотите получать предупреждение и не хотите использовать google guava, вы должны реализовать что-то похожее на guava самостоятельно. Например: [

    private static <T> List<T> typeList(List<?> l, Class<T> klass) {
        List<T> list = new ArrayList<T>();
        for(Object obj : l) {
            if (klass.isAssignableFrom(obj.getClass())) {
                list.add((T) obj);
            }
        }
        return list;
    }

] Эта реализация просто пропускает элементы, которые не являются экземплярами T, но вы также можете генерировать исключение или делать все, что захотите.

0
ответ дан 1 December 2019 в 02:37
поделиться

Пожалуйста, не используйте отражения для подобных вещей!

Я бы рассматривал это как случай трансформации. Возможно что-то вроде

public static <D, S> transform(
    List<D> dst,
    List<S> src,
    Transformer<? extends D, ? super S> transformer
) { ... }

Используйте фабрику для Списка<>, если хотите.

0
ответ дан 1 December 2019 в 02:37
поделиться
Другие вопросы по тегам:

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