Considérez les 2 méthodes suivantes. Le corps est identique - la seule différence est le 2ème paramètre (Rectangle vs RectangleF) des méthodes. Existe-t-il un moyen de combiner ces 2 méthodes en 1 sans compliquer inutilement la liste des paramètres:
public static void DrawRectangles(this Image thisImage, List<RectangleF> rectangles, Color color) {
using (var g = Graphics.FromImage(thisImage)) {
var brush = new SolidBrush(color);
g.FillRectangles(brush, rectangles.ToArray());
}
}
public static void DrawRectangles(this Image thisImage, List<Rectangle> rectangles, Color color) {
using (var g = Graphics.FromImage(thisImage)) {
var brush = new SolidBrush(color);
g.FillRectangles(brush, rectangles.ToArray());
}
3 Réponses :
Je pense que c'est le mieux que vous puissiez faire pour réduire la duplication de code:
private static void DrawRectangles<T>(this Image thisImage, List<T> rectangles, Color color, Action<Graphics, Brush, T[]> fill)
{
using (var g = Graphics.FromImage(thisImage))
{
var brush = new SolidBrush(color);
fill(g, brush, rectangles.ToArray());
}
}
public static void DrawRectangles(this Image thisImage, List<RectangleF> rectangles, Color color)
{
thisImage.DrawRectangles(rectangles, color, (g, b, rs) => g.FillRectangles(b, rs));
}
public static void DrawRectangles(this Image thisImage, List<Rectangle> rectangles, Color color)
{
thisImage.DrawRectangles(rectangles, color, (g, b, rs) => g.FillRectangles(b, rs));
}
Vous pouvez essayer d'utiliser RectangleF.Implicit (Rectangle to RectangleF) Operator , laissez Rectangle to RectangleF puis passez le paramètre.
public static void DrawRectangles(this Image thisImage, List<RectangleF> rectangles, Color color)
{
using (var g = Graphics.FromImage(thisImage))
{
var brush = new SolidBrush(color);
g.FillRectangles(brush, rectangles.ToArray());
}
}
public static void DrawRectangles(this Image thisImage, List<Rectangle> rectangles, Color color)
{
var rectangleFs = rectangles.Select(x => (RectangleF) x).ToList();
DrawRectangles(thisImage, rectangleFs, color);
}
Vous pouvez définir une méthode générique qui prend un paramètre générique comme un IEnumerable.
Nous convertissons ensuite est en tant qu'objet et obtenons son type Rectangle ou RectangleF. Sur la base de cette logique, nous dessinons ensuite le rectangle.
public static void DrawRectangles<T>(this Image thisImage, T rectangles, Color color) where T : IEnumerable
{
using (var g = Graphics.FromImage(thisImage))
{
var brush = new SolidBrush(color);
if (rectangles.Cast<object>().FirstOrDefault().GetType() == typeof(Rectangle))
{
g.FillRectangles(brush, rectangles.Cast<Rectangle>().ToArray());
}
else
{
g.FillRectangles(brush, rectangles.Cast<RectangleF>().ToArray());
}
}
}
public static void Main(string[] args)
{
List<Rectangle> r = new List<Rectangle>();
List<RectangleF> rf = new List<RectangleF>();
r.Add(new Rectangle(10, 10, 10, 10));
rf.Add(new RectangleF(10.4f, 10.4f, 10.4f, 10.4f));
DrawRectangles(new Bitmap(10, 10), rf, Color.Aqua);
}
Pourquoi le paramètre générique T doit-il être ref ?
Je suppose que je me demande quel avantage vous obtiendriez en les combinant? À l'heure actuelle, vous pouvez appeler DrawRectangles avec Rectangle ou RectangleF et le compilateur choisira la méthode correcte à appeler.
Utilisez un meilleur titre.