Надеюсь, это поможет.
Следующее должно работать для вас:
Sub RunIt()
' A, E, 1, 5
PleaseWork 1, 5, 1, 5
End Sub
Sub PleaseWork(intFromCol As Integer, intToCol As Integer, intFromRow As Integer, _
intToRow As Integer)
Dim intI As Integer
Dim intJ As Integer
Dim blnFoundNo As Boolean
Dim strOut As String
strOut = "Yes"
blnFoundNo = False
For intI = intFromCol To intToCol
For intJ = intFromRow To intToRow
' Row , Col
With Worksheets("Calculations").Cells(intJ, intI)
If LCase(Trim(.Value)) = "no" Then
strOut = Replace(Cstr(.Address), "$", "") & " = No"
blnFoundNo = True
Exit For
End If
End With
Next intJ
If blnFoundNo Then Exit For
Next intI
Worksheets("Calculations").Range("H33").Value = strOut
End Sub
Делегаты в C# являются списками указателей метода. Т.е. они хранят ссылки на код, и можно вызвать методы через указатели. Это полезно во многих случаях. Типичный пример для обработчиков событий, где делегаты используются для реализации шаблона издателя/подписчика.
Первая часть вопроса относительно легка: делегаты хранят список указателей функции. При вызове делегата это называет все указатели функции в том внутреннем списке. Добавление и удаление получателя (через Delegate.Combine
и Delegate.Remove
) суммы к добавлению к и удалению из того списка.
Для большей информации низкого уровня обратитесь к ECMA-335 (стандарт CLI), раздел II.14.5 (Указатели метода) и II.14.6 (Делегаты). В частности, обратите внимание, что делегат состоит из указателя экземпляра (типа System.Object
) и указатель метода (типа System.IntPtr
). Указатель метода может быть получен (в CIL) через ldftn
или ldvirtftn
(для вызовов виртуальной функции) инструкции.
Эти два сведения определяют любой метод.
как они могут использоваться эффективно?
Что Вы подразумеваете под этим? Вы знаете о событиях, или Ваш вопрос более специализирован?
Эффективность ре - не ясно, что Вы имеете в виду, но они могут использоваться для достижения эффективности путем предотвращения дорогого отражения. Например, при помощи Delegate.CreateDelegate
создать (введенного) предпроверенного делегата в dynamic/looked-up методе, вместо того, чтобы использовать (медленнее) MethodInfo.Invoke
.
Для тривиального примера (получающий доступ к помехам T Parse(string)
шаблон для типа), посмотрите ниже. Обратите внимание, что это только использует отражение однажды (на тип), а не много времен. Это должно превзойти по характеристикам или отражение или типичный TypeConverter
использование:
using System;
using System.Reflection;
static class Program { // formatted for space
static void Main() {
// do this in a loop to see benefit...
int i = Test<int>.Parse("123");
float f = Test<float>.Parse("123.45");
}
}
static class Test<T> {
public static T Parse(string text) { return parse(text); }
static readonly Func<string, T> parse;
static Test() {
try {
MethodInfo method = typeof(T).GetMethod("Parse",
BindingFlags.Public | BindingFlags.Static,
null, new Type[] { typeof(string) }, null);
parse = (Func<string, T>) Delegate.CreateDelegate(
typeof(Func<string, T>), method);
} catch (Exception ex) {
string msg = ex.Message;
parse = delegate { throw new NotSupportedException(msg); };
}
}
}
Компилятор C# генерирует полноценный класс при создании делегата. Этот класс содержит список ссылок на функцию, как Konrad упомянул. Хорошая вещь о делегатах состоит в том, что они предоставляют Вам простой способ выполнить задачу асинхронно с обратным вызовом уведомления. То, что это означает, - то, что Вы можете быть уведомлены, когда Ваша фоновая работа завершается. Пул потоков не обеспечивает эту функцию. Делегаты являются обширной темой, и я нахожу Jeff Richter (CLR через C#) и книги Albahari (C#3) конкретной справки.
Делегаты C# являются объектами (проверьте Систему. Класс делегата), которые инкапсулируют ссылку на объект и указатель метода. У них может также быть нулевая ссылка для возражения для представления вызова статическому методу.
При вызове делегата с аргументами делегат обрабатывает вызов к методу, на который ссылаются, на ссылочном объекте с указанными аргументами.
Скомпилированный делегат Вызывает метод, непосредственно обрабатывается временем выполнения (как видимый с Отражателем):
[MethodImpl(0, MethodCodeType=MethodCodeType.Runtime)]
public virtual void Invoke(T obj);
Использование во время выполнения вся информация внутренне для компиляции вызова стандартного метода в метод, на который ссылаются.