Объявлять экземпляр универсального типа динамически [дубликат]

Один из способов решения - предоставить статический заводский метод для распределения массива, если по какой-либо причине вы хотите предоставить конструктору закрытый.

static Car*  Car::CreateCarArray(int dimensions)

Но почему вы сохраняете один конструктор общедоступным и другим частным?

Но каким-то еще одним способом является объявление публичного конструктора со значением по умолчанию

#define DEFAULT_CAR_INIT 0
Car::Car(int _no=DEFAULT_CAR_INIT);
30
задан benPearce 21 November 2008 в 05:47
поделиться

7 ответов

Если Вы не знаете тип во время компиляции, но Вы хотите фактический тип (т.е. не List<object>) , и Вы не находитесь в общем методе / тип с соответствующим параметром типа, то необходимо использовать отражение.

Для создания отражения более простым я иногда представлял новый универсальный тип или метод в моем собственном коде, таким образом, я могу назвать это отражением, но тогда просто использовать нормальные дженерики после этого. Например:

object x = GetObjectFromSomewhere();
// I want to create a List<?> containing the existing
// object, but strongly typed to the "right" type depending
// on the type of the value of x
MethodInfo method = GetType().GetMethod("BuildListHelper");
method = method.MakeGenericMethod(new Type[] { x.GetType() });
object list = method.Invoke(this, new object[] { x });

// Later

public IList<T> BuildListHelper<T>(T item)
{
    List<T> list = new List<T>();
    list.Add(item);
    return list;
}

, Конечно, Вы не можете сделать очень много со списком впоследствии, если Вы не знаете тип... вот почему, такого рода вещь часто падает. Не всегда, хотя - я использовал что-то как вышеупомянутое в нескольких случаях, где система типов просто не вполне позволяет мне выразить все, которое я должен статически.

РЕДАКТИРОВАНИЕ: Обратите внимание на это, хотя я называю Тип. GetMethod в коде выше, если бы Вы собирались выполнить его много, который Вы, вероятно, хотели бы просто назвать им однажды - в конце концов, метод, не собирается изменяться. Можно быть в состоянии сделать его статичным (Вы могли в случае выше), и Вы, вероятно, хотите сделать его частным также. Я оставил его, как общедоступный метод экземпляра для простоты GetMethod звонит в пример кода - необходимо будет определить соответствующие обязательные флаги иначе.

46
ответ дан Jon Skeet 21 November 2008 в 05:47
поделиться
  • 1
    Эти -H 'Accept: application/vnd.github.v3.raw' необходимо? Я смог получить доступ к частному файлу без той части. – Nick Chammas 12 June 2015 в 17:33

Я думаю лучшее, которое Вы собираетесь быть способными сделать, что-то вроде этого:

static void Main(string[] args)
{
    int i = 1;
    var thelist = CreateList(i);
}

public static List<T> CreateList<T>(T t)
{
    return new List<T>();
}
1
ответ дан Nathan 21 November 2008 в 05:47
поделиться
  • 1
    @NickChammas: без того заголовка я получаю ответ JSON с метаданными и фактическим содержанием файла base64 закодированный, а не файл как простой текст. – c24w 15 July 2015 в 12:57

Можно также использовать Активатор. CreateInstance. Отрывок примера кода:

public class BaseRepository<T> where T : DataContext
{
   protected T _dc;

   public BaseRepository(string connectionString)
   {
      _dc = (T) Activator.CreateInstance(typeof(T), connectionString);
   }

   public void SubmitChanges()
   {
      _dc.SubmitChanges();
   }
}
1
ответ дан KevinT 21 November 2008 в 05:47
поделиться
  • 1
    @thomasfuchs I' ve пропустил что-то очевидное с путем к файлу. Можно ли явно определить безопасный файл README.md в команде для демонстрации? – anon58192932 4 October 2016 в 05:03

Вполне уверенный можно сделать это, они не должны быть зафиксированы во время компиляции как шаблоны в C++.

пример, который подобен здесь: http://geekswithblogs.net/marcel/archive/2007/03/24/109722.aspx

0
ответ дан seanb 21 November 2008 в 05:47
поделиться
  • 1
    Этот didn' t работают на меня. Это просто возвратилось 404. – EM0 9 November 2016 в 19:08

Если бы Вы не знаете тип во время проектирования, я сказал бы, что у Вас есть список ОБЪЕКТОВ (базовый класс для всех других типов).

List<object> list = new List<object>();
1
ответ дан abelenky 21 November 2008 в 05:47
поделиться
  • 1
    Что, если вышеупомянутая команда дает ошибку как завихрение: (56) ПОДКЛЮЧЕНИЕ Прокси, прерванное, что, это означает. – Max 28 August 2015 в 13:45

Посмотрите, что ответ от подобного вопроса "Динамично Создает Универсальный Тип для Шаблона" . Единственная разница - то, что они генерируют тип из командной строки, остальные необходимо быть в состоянии адаптироваться к потребностям.

Как в стороне, Вы не можете назвать typeof на экземпляре - для получения типа экземпляра (например, "я" называю GetType ():

Type intType = i.GetType();
0
ответ дан Community 21 November 2008 в 05:47
поделиться
  • 1
    @EM0 - Я просто попробовал, это работало. Несколько вещей, которые стоит перепроверить: 1. часть, относящаяся к хосту, raw.githubusercontent.com, 2. путь, <username>/<repo name>/<branch>/<file name> 3. маркер должен иметь repo объем доступа. – theartofrain 9 November 2016 в 19:13

Если Вы все еще хотите ввести.Add ().Remove (), сделайте foreach и т.д., можно рассматривать Список как регулярную "старую" Систему. Наборы. IList, так как этот интерфейс к счастью реализован List< T>.

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

Type T = typeof ( string ); // replace with actual T
string typeName = string.Format (
  "System.Collections.Generic.List`1[[{0}]], mscorlib", T.AssemblyQualifiedName );

IList list = Activator.CreateInstance ( Type.GetType ( typeName ) )
  as IList;

System.Diagnostics.Debug.Assert ( list != null ); //

list.Add ( "string 1" ); // new T
list.Add ( "string 2" ); // new T
foreach ( object item in list )
{
  Console.WriteLine ( "item: {0}", item );
}
0
ответ дан baretta 21 November 2008 в 05:47
поделиться
  • 1
    Да, that' s путь. Я взял путь от " Download" ссылка для файла, но разделенный "? маркер =..." от конца и добавил маркер. Это действительно имеет repo объем доступа, но это только говорит об общедоступных репозиториях. Это - организация частный репозиторий. Кроме того, нам включили аутентификацию с 2 факторами, но я думаю если that' s проблема it' s предполагаемый дать ошибку 401, не 404. – EM0 9 November 2016 в 19:24
Другие вопросы по тегам:

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