Это мои 2 цента на основе ответа Grax , но с двумя параметрами, необходимыми для общего метода.
Предположим, что ваш метод определяется следующим образом в классе Helpers:
public class Helpers
{
public static U ConvertCsvDataToCollection(string csvData)
where U : ObservableCollection
{
//transform code here
}
}
В моем случае тип U всегда является наблюдаемым объектом хранения коллекции типа T.
Поскольку у меня есть предопределенные типы, я сначала создаю «фиктивные» объекты, которые представляют наблюдаемый набор (U) и объект, хранящийся в нем (T), и который будет использоваться ниже, чтобы получить их тип при вызове Make
object myCollection = Activator.CreateInstance(collectionType);
object myoObject = Activator.CreateInstance(objectType);
Затем вызовите GetMethod, чтобы найти вашу общую функцию:
MethodInfo method = typeof(Helpers).
GetMethod("ConvertCsvDataToCollection");
До сих пор вышеупомянутый вызов в значительной степени идентичен тому, что было объяснено выше, но с небольшой разницей, когда вам нужно передать ему несколько параметров.
Вам нужно передать массив Type [] в функцию MakeGenericMethod, которая содержит типы «фиктивных» объектов, которые были созданы выше:
MethodInfo generic = method.MakeGenericMethod(
new Type[] {
myCollection.GetType(),
myObject.GetType()
});
Как только это будет сделано, вам нужно вызвать метод Invoke, как указано выше.
generic.Invoke(null, new object[] { csvData });
И все готово.
UPDATE:
Поскольку @Bevan выделен, мне не нужно создавать массив при вызове функции MakeGenericMethod, поскольку он принимает параметры, и мне не нужно создавать объект, чтобы получить типы, поскольку я могу просто передать типы непосредственно этой функции. В моем случае, поскольку у меня есть типы, предопределенные в другом классе, я просто изменил свой код на:
object myCollection = null;
MethodInfo method = typeof(Helpers).
GetMethod("ConvertCsvDataToCollection");
MethodInfo generic = method.MakeGenericMethod(
myClassInfo.CollectionType,
myClassInfo.ObjectType
);
myCollection = generic.Invoke(null, new object[] { csvData });
myClassInfo содержит 2 свойства типа Type
, которые я установил во время выполнения на основе перечисления значение передается конструктору и предоставит мне соответствующие типы, которые затем я использую в MakeGenericMethod.
Еще раз спасибо за выделение этого @Bevan.
Pre beta 5 это был тройной сдвиг. Apple изменила (или сломала) см. этот вопрос (на который нет ответа).
Я только что установил «slowmo», как упомянуто выше, и он работает на симуляторе 3.2. Мне понадобилось время, чтобы понять, как включить его. Вы должны проверить «симулировать аппаратную клавиатуру» в аппаратном меню симулятора, а затем быстро нажать клавишу Shift вашего Mac 3 раза, чтобы включить или выключить его.
Я не совсем уверен, но замечаю, что переключение «демонстрационного режима» в меню иногда помогает, а иногда - нет. Я также не совсем уверен, есть ли на самом деле функция замедленного воспроизведения или это ошибка симулятора.
Для этого AFAIK не содержит дурацких решений Java, но если преобразование должно быть выполнено на стороне сервера, я бы рекомендовал вам использовать конвертер pdf2ps Ghostscript. Даже если вам придется установить конкретную для платформы версию Ghostscript, вы должны найти ее для всех упомянутых платформ.
-121--4055923-После поиска и нескольких разрывов при атаке на другие проблемы я нашел ответ, который ясен и лаконичен (для стандартных, в любом случае):
Вызов функции через выражение, тип функции которого имеет языковую связь, отличную от языковой связи типа функции определения вызываемой функции, не определен. [5,2,2/1]
Я все еще утверждаю, что на фундаментальном уровне проблематично использовать текст из стандарта C++ для определения поведения библиотеки C, скомпилированной с компилятором C, и как именно работает эта межязыковая совместимость, очень специфична для реализации; однако это самое близкое, я думаю, что любой стандарт может (в настоящее время) надеяться определить такое взаимодействие.
В частности, это неопределенное поведение (и не использует библиотеку C, так что проблема не возникает):
void call(void (*pf)()) { pf(); } // pf() is the UB
extern "C" void f();
int main() { call(f); }
// though I'm unsure if a diagnostic is required for call(f)
Comeau дает диагностику по вызову (f)
(хотя она может сделать это, даже если диагностика не требуется).
Это не неопределенное поведение, и показывает, как включить связь языка в тип указателя функции (который через typedef):
extern "C" typedef void F();
void call(F* pf) { pf(); }
extern "C" void f();
int main() { call(f); }
Или может быть написано:
extern "C" {
typedef void F();
void f();
}
void call(F* pf) { pf(); }
int main() { call(f); }
-121--1458377- Вы можете загрузить «slowmo» из http://mschrag.github.com/ , чтобы повторно включить функцию замедленного движения, позволяя переключаться между режимами.
Я протестировал его на iPhone Simulator 3.1 (139.1) и он все еще работает.
Запустите сценарий slowmo.sh при загрузке, затем нажмите клавишу shift 3 раза подряд.