Я должен использовать универсальный интерфейс как следующее:
public interface IContainer
{
IEnumerable> Contents { get; }
}
Объект, реализовывая этот интерфейс возвращается общим методом как следующее:
IContainer GetContainer(IProperty property);
Ввести T
неизвестно до времени выполнения.
Используя отражение я могу вызвать GetContainer
метод и получает результат.
Моя проблема состоит в том, что я не знаю, как перечислить результат, который имеет тип Object
(поэтому я не могу бросить его к IEnumerable
).
Я также попытался бросить следующим образом, но это не работает (это говорит, что "Тип ожидается"):
var myContainer = genericMethodInfo.Invoke(
myService,
new object[] { property })
as typeof(IContainer<>).MakeGenericType(type);
где type
тип выполнения, myService
сервис, выставляющий GetContainer
метод, и property
имеет тип IProperty
по мере необходимости.
ОБНОВЛЕНИЕ: посмотрите мое полное решение в моем блоге: http://stefanoricciardi.com/2010/02/18/generics-with-type-uknown-at-compile-time/
typeof (IContainer <>).MakeGenericType (тип) только оценит во времени выполнения, в то время как «как» потребности знать тип во время компилятора.
Я действительно не понимаю этот комментарий: Моя проблема в том, что я не знаю, как перечислить результат, который имеет тип Object (поэтому я не могу привести его к IEnumerable).
myContainer может быть Объектом, но его можно без сомнения привести к IEnumerable? Если он не может, его нельзя перечислить.
Если вы думаете о переходе на .Net 4, это то, что обеспечивает тип dynamic.
. Я предполагаю, что ваш объект будет возвращен только как один из ограниченного числа типов, поэтому почему бы не протестировать их перед кастингом, например если объект относится к этому классу?
По существу, необходимо отслеживать объект с помощью видео. Существует несколько способов сделать это с помощью OpenCV , которые описаны на их странице Анализ движения и отслеживание объектов .
-121--5085980-Также пользовательский компаратор здесь, если вы хотите, чтобы -1 появился первым, но остальные будут по убыванию , но как-то я нахожу его более элегантным:) Обратите внимание, что он сделан для ints
class Comparer : IComparer<int>
{
public int Compare(int x, int y)
{
if (x == -1 || y == -1) return x - y;
return y - x;
}
}
-121--4605214- Ваш тип T должен быть известен компилятору, поэтому это не будет работать Вы можете попробовать сделать не универсальную версию вашего интерфейса, как это:
public interface IContainer
{
IEnumerable<IContent> Contents { get; }
}
public interface IContainer<T> : IContainer { ... }
Таким образом вы имеете что-то для приведения и способны использовать его.
Во-первых, при приведении вам нужен тип (double, int); typeof принимает аргумент типа и возвращает класс типа Type.
object x = 0.0;
Type t = typeof(double);
double y = x as t; //does not compile - t is not a type - it's an instance of type Type
double y = x as typeof(double); //same as above
double y = x as double; //compiles - double is a type
Type z = x as Type; //compiles - Type is a type
Во-вторых, вот пример кода:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Reflection;
using System.Diagnostics;
namespace TryThis
{
public interface IContainer<T>
{
IEnumerable<IContent<T>> Contents { get; }
}
public interface IContent<T>
{
T GetMyContent();
}
public interface IProperty
{ }
public class Content<T> : IContent<T>
{
T m_content = default(T);
public T GetMyContent() { return m_content; }
public Content(T val) { m_content = val; }
}
public class Contents<T> : IEnumerable<IContent<T>>
{
List<IContent<T>> m_contents = new List<IContent<T>>();
IEnumerator<IContent<T>> IEnumerable<IContent<T>>.GetEnumerator() { return m_contents.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return m_contents.GetEnumerator(); }
public Contents(params T[] contents) { foreach (T item in contents) m_contents.Add(new Content<T>(item)); }
}
public class TestGenericContent : IContainer<int>
{
public IContainer<int> GetContainer(IProperty property) { return this; }
public IEnumerable<IContent<int>> Contents { get { return new Contents<int>(1, 2, 3); } }
}
public static class TryThisOut
{
static void Test2(object o)
{
Type t = o.GetType();
Type tInterface = t.GetInterface("IContainer`1"); //could be null if o does not implement IContainer<T>
Type tGenericArg = tInterface.GetGenericArguments()[0]; //extracts T from IContainer<T>
MethodInfo info = t.GetMethod("GetContainer");
IProperty propArg = null; //null in this example
object oContainer = info.Invoke(o, new object[] { propArg });
PropertyInfo prop = tInterface.GetProperty("Contents");
object oContents = prop.GetGetMethod().Invoke(oContainer, null);
//oContents is of type IEnumerable<IContent<T>>, which derives from IEnumerable, so we can cast
IEnumerable enumeratedContents = oContents as IEnumerable;
MethodInfo getContentItem = typeof(IContent<>).MakeGenericType(tGenericArg).GetMethod("GetMyContent");
foreach (object item in enumeratedContents)
{
object oContentItem = getContentItem.Invoke(item, null);
Debug.Print("Item {0} of type {1}", oContentItem, oContentItem.GetType());
//...
}
}
public static void Test()
{
object o = new TestGenericContent();
Test2(o);
}
}
}
Извините, если я неправильно понял, у меня возникли проблемы с точным пониманием какова была ваша цель. Вы искали что-то подобное?
var myContainer = typeof(ClassWithGetContainer)
.GetMethod("GetContainer")
.MakeGenericMethod(runtimeType)
.Invoke(InstanceOfClassWithGetContainer, new object[] { property });