да, есть способы. С C # 3.0 у вас есть тип Func<T>
, который делает это.
Например, я написал это вчера:
var image = Image.FromFile(_file);
int height = image.Height;
int width = image.Width;
double tan = height*1.00/width;
double angle = (180.0 * Math.Atan(tan) / Math.PI);
var bitmap = new System.Drawing.Bitmap(image, width, height);
var g = System.Drawing.Graphics.FromImage(bitmap);
int fontsize = 26; // starting guess
Font font = null;
System.Drawing.SizeF size;
Func<SizeF,double> angledWidth = new Func<SizeF,double>( (x) =>
{
double z = x.Height * Math.Sin(angle) +
x.Width * Math.Cos(angle);
return z;
});
// enlarge for width
do
{
fontsize+=2;
if (font != null) font.Dispose();
font = new Font("Arial", fontsize, System.Drawing.FontStyle.Bold);
size = g.MeasureString(_text, font);
}
while (angledWidth(size)/0.85 < width);
Цель состояла в том, чтобы добавить водяной знак к существующему изображению. Я хотел, чтобы размер водяного знака составлял около 85% ширины изображения. Но я хотел наклонить текст водяного знака так, чтобы он был написан под углом. Это выявило необходимость выполнения некоторых триггерных вычислений на основе углов, и мне нужна была небольшая функция для выполнения этой работы. Func
идеально подходит для этого.
Приведенный выше код определяет Func
(функция), которая принимает SizeF
и возвращает double
для фактической ширины текста, когда он рисуется под заданным углом. Эта Func
является переменной внутри функции, а сама переменная содержит функцию (ссылку на a). Затем я могу вызвать эту «приватную» функцию в той области, где я ее определил. Func имеет доступ к другим переменным, которые определены перед ним, в своей области выполнения. Таким образом, переменная angle
доступна в функции angledWidth()
.
Если вам нужна активируемая логика, которая возвращает void
, вы можете использовать Action<T>
таким же образом. .NET определяет дженерики Func, которые принимают N аргументов, поэтому вы можете сделать их довольно сложными. Func - это как функция VB или метод C #, который возвращает не void; Действие похоже на VB Sub или метод C #, который возвращает void.