Вот пара чистых версий R. Скорее всего, это будет так же быстро, как переход на C / C ++, но один из них может быть достаточно быстрым для ваших нужд и будет легче поддерживать:
# 1 Reduce
cumsum.bounded <- function(x, lower.bound = 0, upper.bound = 500) {
bsum <- function(x, y) min(upper.bound, max(lower.bound, x+y))
if (length(x) > 1) Reduce(bsum, x, acc = TRUE) else x
}
# 2 for loop
cumsum.bounded2 <- function(x, lower.bound = 0, upper.bound = 500) {
if (length(x) > 1)
for(i in 2:length(x)) x[i] <- min(upper.bound, max(lower.bound, x[i] + x[i-1]))
x
}
Возможно, это немного улучшится, если x
имеет длину 0 или 1 в зависимости от того, насколько строгими являются требования.
Вы можете использовать относительное связывание с поздним связыванием IDispatch в C #.
http://support.microsoft.com/kb/302902
Вот пример использования Excel. Таким образом, вам не нужно добавлять ненужную зависимость от распухшей Microsoft PIA:
//Create XL
Object xl = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
//Get the workbooks collection.
// books = xl.Workbooks;
Object books = xl.GetType().InvokeMember( "Workbooks",
BindingFlags.GetProperty, null, xl, null);
//Add a new workbook.
// book = books.Add();
Objet book = books.GetType().InvokeMember( "Add",
BindingFlags.InvokeMethod, null, books, null );
//Get the worksheets collection.
// sheets = book.Worksheets;
Object sheets = book.GetType().InvokeMember( "Worksheets",
BindingFlags.GetProperty, null, book, null );
Object[] parameters;
//Get the first worksheet.
// sheet = sheets.Item[1]
parameters = new Object[1];
parameters[0] = 1;
Object sheet = sheets.GetType().InvokeMember( "Item",
BindingFlags.GetProperty, null, sheets, parameters );
//Get a range object that contains cell A1.
// range = sheet.Range["A1];
parameters = new Object[2];
parameters[0] = "A1";
parameters[1] = Missing.Value;
Object range = sheet.GetType().InvokeMember( "Range",
BindingFlags.GetProperty, null, sheet, parameters );
//Write "Hello, World!" in cell A1.
// range.Value = "Hello, World!";
parameters = new Object[1];
parameters[0] = "Hello, World!";
objRange_Late.GetType().InvokeMember( "Value", BindingFlags.SetProperty,
null, range, parameters );
//Return control of Excel to the user.
// xl.Visible = true;
// xl.UserControl = true;
parameters = new Object[1];
parameters[0] = true;
xl.GetType().InvokeMember( "Visible", BindingFlags.SetProperty,
null, xl, Parameters );
xl.GetType().InvokeMember( "UserControl", BindingFlags.SetProperty,
null, xl, Parameters );
Необходимо ожидать C# 4.0 для выхода для получения позднего связывания, которое Вы ищете. Любое время мне нужны interop возможности, которые я переключаю назад на режим VB.Net, таким образом, я могу использовать в своих интересах возможности COM, в которых C#, кажется, испытывает недостаток.
простой метод, который я использую, создает класс в VB.Net, который делает работу IDispatch и затем представление методов, которые я хочу использовать в качестве методов своей обертки, и затем я могу назвать их по желанию от моего кода C#. Не самое изящное из решений, но это вытащило меня из затора или два за прошлые несколько месяцев.
Ключевое слово dynamic
в C # 4 поддерживает IDispatch и позднюю привязку. Вы можете прочитать динамическую серию Сэма Нга для получения дополнительной информации
О, и C # 4 доступен только как CTP сегодня. Вам придется либо подождать, пока Visual Studio vNext, либо использовать бета-версию (которая работает на виртуальном ПК с Windows Server 2008), чтобы использовать это.
Как уже говорили другие - использование «динамического» ключевого слова в c # 4. Вот простой пример - он гораздо более лаконичен, чем «InvokeMethod»
dynamic xl = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
dynamic books = xl.Workbooks;
dynamic book = books.Add();
Console.WriteLine(books.Count); //Writes 1
foreach (dynamic b in books)
{
Console.WriteLine(b.Name); //Writes "Book1"
}
эй, чувак, у меня есть 2 проекта codeplex в настоящее время, чтобы решить эту проблему.
первым является LateBindingApi.Excel http://excel.codeplex.com сопоставленный вызов с поздним связыванием для хорошо известной объектной модели. это был тестовый проект для следующего проекта.
вторым является CodeGenerator http://latebindingapi.codeplex.com , инструмент создает проекты c # из библиотек COM Type. сгенерированные проекты включают объекты мапперов с поздней привязкой, обращающиеся к COM-серверу. основным моментом является то, что инструмент преобразует библиотеки типов COM в разных версиях в один проект (например, Excel 9,10,11) и помечает все объекты с помощью самоопределенного атрибута SupportByLibrary. Я проанализировал все офисные приложения в версии 9,10,11,12,14 с помощью этого инструмента и сгенерировал решение c #, которое доступно в виде протестированной бета-версии с примером кода на главной странице.
, вероятно, вам удастся обойтись более красивым кодом в C # 2.0 / 3.0, если вы потратите время на написание интерфейса. содержащие методы и свойства объекта, которые вы хотите получить, и добавить некоторые атрибуты (я записываю их из памяти, поэтому детали могут быть неправильными, но я клянусь, что у меня это сработало ...)
using System.Runtime.Interopservices;
[Guid("00024500-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
interface IExcel
{
// sample property
string Name{get;}
// more properties
}
// and somewhere else
void main()
{
Object xl = Activator.CreateInstance(Type.GetTypeFromProgID("Excel.Application"));
IExcel excel = (IExcel)xl;
string name = xl.name
}
Как уже упоминалось, код не будет работать "из коробки" это скорее подсказка, что искать в msdn.