Строго типизированный объект из строкового типа name (C #) - PullRequest
4 голосов
/ 30 января 2010

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

  • Запрос на общие элементы хранилища (они сохраняют свой тип в виде строки)
  • Если элемент является подклассом SearchCriteria, создайте правильный экземпляр
  • Добавить экземпляр в список (SearchCriteria является суперклассом)

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

Итак, мой вопрос, есть ли "общий" способ создания экземпляра, который строго типизирован, используя строку в качестве "источника" для типа.

Я знаю, что могу использовать Reflection для создания экземпляра, но это объект типа, поэтому я не смог бы добавить его в список. О, только что пришла идея ... Создать объект, используя отражение, привести его к супертипу (SearchCrit), добавить в список. Надеюсь, реальный тип все еще должен быть «правильным подтипом» ...

Попробую и обновлю этот пост с результатами. Есть идеи получше?

Chris

   private IList<SearchCriteria> _searchCriteriaAll;
    public IList<SearchCriteria> SearchCriteriaAll
    {
        get
        {
            if (_searchCriteriaAll == null)
            {
                _searchCriteriaAll = new List<SearchCriteria>();
                var tN = typeof (SearchCriteria).ToString();
                foreach (var o in DataStorage.LinkedObjects)
                {
                    if (tN.StartsWith(o.TypeName))
                    {
                        if (o.TypeName == typeof(StringSearchCriteria).ToString())
                            _searchCriteriaAll.Add(new StringSearchCriteria(o));
                    }
                }
            }
            return _searchCriteriaAll;
        }
    }

EDIT:

Спасибо за подсказки, «правильный» путь определенно будет заводским. Я посмотрю на это. На данный момент я использую этот хак, потому что подклассы такие маленькие, я не хочу фабрику для каждого .. (и это место в настоящее время единственное с такой "необычной" функцией)

   private IList<SearchCriteria> _searchCriteriaAll;
    public IList<SearchCriteria> SearchCriteriaAll
    {
        get
        {
            if (_searchCriteriaAll == null)
            {
                _searchCriteriaAll = new List<SearchCriteria>();
                var tN = typeof (SearchCriteria).ToString();
                foreach (var o in DataStorage.LinkedObjects)
                {
                    if (tN.StartsWith(o.TypeName))
                    {
                        var newO = Activator.CreateInstance(typeof(SearchCriteria).Assembly.FullName, o.TypeName);
                        var newCrit = newO.Unwrap() as SearchCriteria;
                        newCrit.DataStorage = o;
                        _searchCriteriaAll.Add(newCrit);
                    }
                }
            }
            return _searchCriteriaAll;
        }
    }

Ответы [ 3 ]

3 голосов
/ 31 января 2010

Обобщения и рефлексия не заводят хороших друзей. Более простой подход заключается в использовании интерфейса неуниверсального списка:

_searchCriteriaAll = new List<SearchCriteria>();
IList list = (IList) _searchCriteriaAll;
...
Type type = typeof(SearchCriteria).Assembly.GetType(o.TypeName);
list.Add(Activator.CreateInstance(type));

(где o.TypeName включает информацию о пространстве имен, но не обязательно должна быть квалифицирована для сборки)

Это по-прежнему безопасно для типов во время выполнения (оно будет выбрасываться во время выполнения, если оно неверно), и все еще корректирует тот же список.

Обратите внимание, что мы смотрим внутрь Assembly только через Assembly.GetType().

0 голосов
/ 30 января 2010

Мне не совсем понятно, чего вы пытаетесь достичь, но вы можете создать тип из строки, подобной этой:

var t = Type.GetType(typeName);

Если вы хотите проверить, является ли это правильный подтип, вы можете использовать метод IsAssignableFrom .

0 голосов
/ 30 января 2010

Я бы сказал, что вы ищете Шаблон фабричного метода .

Здесь есть образец C # здесь - первая ссылка лучше объясняет шаблон, вторая - правильный язык для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...