Динамическая типизация в C#

Я знаю, что это не работает, но у кого-нибудь есть способ заставить это работать?

object obj = new object();
MyType typObj = new MyType();
obj = typObj;
Type objType = typObj.GetType();
List<objType> list = new List<objType>();
list.add((objType) obj);

РЕДАКТИРОВАТЬ:

Вот текущий код: http://github.com/vimae/Nisme/blob/4aa18943214a7fd4ec6585384d167b10f0f81029/Lala.API/XmlParser.cs

Метод, который я пытаюсь упростить, — это SingleNodeCollection.

Как вы можете видеть, в настоящее время он использует настолько наколотые методы отражения.


person WedTM    schedule 04.06.2009    source источник
comment
чего вы пытаетесь достичь?   -  person Mitch Wheat    schedule 04.06.2009
comment
@Daniel: Похоже, он пытается создать список типа уже существующего объекта.   -  person Welbog    schedule 04.06.2009
comment
И зачем использовать new object(), если вы собираетесь его уничтожить (obj = typObj)?   -  person John Saunders    schedule 04.06.2009
comment
Какая часть этого не работает? Вы получаете ошибку компилятора или исключение времени выполнения?   -  person JSBձոգչ    schedule 04.06.2009
comment
@JS Bangs: List‹objType› list... не работает, потому что objType — это переменная, а не тип.   -  person mmmmmmmm    schedule 04.06.2009


Ответы (8)


Кажется, вам не хватает очевидного решения:

object obj = new object();
MyType typObj = new MyType();
obj = typObj;
List<MyType> list = new List<MyType>();
list.Add((MyType) obj);

Если вам действительно нужен динамический маршрут, вы можете сделать что-то вроде этого:

object obj = new object();
MyType typObj = new MyType();
obj = typObj;
Type objType = typObj.GetType();

Type listType = typeof(List<>);
Type creatableList = listType.MakeGenericType(objType);

object list = Activator.CreateInstance(creatableList);
MethodInfo mi = creatableList.GetMethod("Add");
mi.Invoke(list, new object[] {obj});
person Jeff Moser    schedule 04.06.2009

Вам нужно отражение:

constructor = typeof (MyType).GetConstructor () // doing this from memory, the typeof might be wrong, I'm sure someone will edit it
typObj = (MyType) constructor.Invoke ()

Это также можно сделать для дженериков, но это немного сложнее.

person Skizz    schedule 04.06.2009

Вы можете сделать что-то подобное, используя Generics, хотя я не совсем уверен, в чем смысл этого.

public List<T> TypedList<T>() where T : new()
{
    object obj = new object();
    T typObj = new T();
    obj = typObj;
    List<T> list = new List<T>();
    list.Add((T)obj);
    return list;
}
person rmoore    schedule 04.06.2009

object obj = new object();
Type objType = obj.GetType();
IList list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(objType));
list.Add(obj);

При этом вы получите ошибку времени выполнения, если попытаетесь поместить в список что-то, что не может быть назначено из objType.

person Kleinux    schedule 04.06.2009

Хотя кажется, что ответил, я все еще не понимаю :)

Разве не было бы полезно иметь «typeToReturn» в качестве общего аргумента функции?

public List<T> SingleNodeCollection<T>(String xPath, XPathNavigator navigator)
  where T : new()
{
  XPathNodeIterator nodes = navigator.Select(xPath);
  List<T> returnedList = new List<T>(nodes.Count);
  ...
  T newObj = new T();
  ...
  Type t = typeof(T); // need the type anyway?
}
person flq    schedule 02.07.2009

  public class myClass
  {
  }

  myClass instance = new myClass();

  Type t = instance.GetType;

//top просто показывает получение типа...

public object GetListOfType(Type t)
{
  Type listType = typeof(List<>);
  var listOfType = listType.MakeGenericType(t);

  var listOfMyClassInstance = Activator.CreateInstance(listOfType); 

  return listOfMyClassInstance;
}

но в конце концов вам придется бросить... используя свой тип напрямую

  List<object> listOfMyClass = GetListOfType(t);
  listOfMyClass.Add(myClassInstance);

  ((myClass)listOfMyClass[0]).SomeProperty
person Pawel Cioch    schedule 29.04.2011

Быстрее было бы использовать Reflection.Emit вот простой пример использования Reflection.Emit для создания экземпляра произвольного конкретного типа во время выполнения. Для ваших целей вам просто нужно, чтобы он вызывал ctor List вместо T.ctor, как в примере.

person Krypes    schedule 04.06.2009

Я не совсем уверен, что вы пытаетесь сделать, но будет ли это работать:

var obj = new MyType();

Хотя я могу неправильно понять ваш вопрос.

(Я отредактировал это, чтобы исправить пример кода, который не компилировался, спасибо за комментарий)

person marcc    schedule 04.06.2009
comment
вар объект; является недействительной декларацией. var — неявное ключевое слово, означающее, что компилятор сам определит тип. С оператором var obj; компилятору не хватило бы информации для определения типа. - person Timothy Carter; 04.06.2009