Неявное набрание массивов, которые реализуют интерфейсы

StackOverflow https://stackoverflow.com/questions/2799902

  •  04-10-2019
  •  | 
  •  

Вопрос

У меня было впечатление, что компилятор C # подразумевается, что компилятор C # подчеркнут массив, основанный на том, что они все могут быть неявно преобразованы в.

Компилятор генерируетЛучший тип не найдено для неявного набранного массива

public interface ISomething {}

public interface ISomething2 {}

public interface ISomething3 {}

public class Foo : ISomething { }
public class Bar : ISomething, ISomething2 { }
public class Car : ISomething, ISomething3 { }

void Main()
{
    var obj1 = new Foo();
    var obj2 = new Bar();
    var obj3 = new Car();

    var objects= new [] { obj1, obj2, obj3 };
}

Я знаю, что путь исправить это - объявить тип как:

new ISomething [] { obj1, ...} 

Но я после того, как под охватами типа помогите здесь.

Это было полезно?

Решение

Компилятор C # рассматривает набор типов всех указанных элементов. Оно делает нет Рассмотреть общие типы базовых типов и т. Д.

Ты мог лить один из выражений:

var objects= new [] { obj1, obj2, (ISomething) obj3 };

... но лично я просто использовал явную форму:

var objects= new ISomething[] { obj1, obj2, obj3 };

В качестве альтернативы, если вы явно объявили ни один или все obj1, obj2 а также obj3 как тип ISomething, это тоже будет работать нормально, не изменив выражение инициализации массива.

С спецификации C # 3, раздел 7.5.10.4:

Экспрессия создания массива третьей формы называется Неявно набранное выражение создания массива. Отказ Это похоже на вторую форму, за исключением того, что тип элемента массива не дан явно, но определяется как лучший общий тип (§7.4.2.13) набора выражений в инициаторов массива.

Раздел 7.4.2.13 Похоже:

В некоторых случаях обычный тип должен быть выведен для набора выражений. В частности, типы элементов неявно напечатанных массивов и возвратных типов анонимных функций с блочными телами находятся таким образом. Интуитивно, учитывая набор выражений E1 ... EM Этот вывод должен быть эквивалентен вызову метода

Tr M<X>(X x1 … X xm)

с Ei как аргументы. Точнее, вывод запускается с нефиксированной переменной типа X. Выводки вывода затем выполняются из каждого Ei с типом X. Наконец, X фиксирован, а полученный тип S является полученным общим типом для выражений.

Другие советы

Если все экземпляры могут быть отброшены на тип любого экземпляра, чем этот тип будет использоваться. Для всех случаев не хватает общего типа, иначе инициализация массива INQUITITITITITITITITITITITITITITITITITITITITITITITITITITITE всегда будет успешной и часто генерировать нежелательные new object[] массивы

Как небольшое дополнение к ответу Skeet:

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

public static IWindsorInstaller[] MobileRestComponentInstallers
        {
            get
            {
                return new []
                           {
                                 new RepositoryInstaller(),
                                 new AppSettingsInstaller(),
                                 // tens of other installers...
                                 GetLoggerInstaller() // public IWindsorInstaller GetLoggerInstaller()...
                           };
            }
        }

Это будет работать, но пожалуйста, не сделайте это :) Просто определите тип массива и измените new[] к new IWindsorinstaller[]Отказ Это гораздо более читаемое, имеющее явно определить тип массива.

Do like this for Class object( UIViewController) initialization in var array:



 var page1 = new Class1();
 var page2 = new Class2();
 var pages = new UIViewController[] { page1, page2 };

Примечание: здесь UiviewController может быть любым классом

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top