[英]How Can A Non-Abstract Property of a Predefined Abstract Class Be Accessed?
我用派生類的對象填充了一個 ICanvasEffect 類型的數組,例如 GaussianBlurEffect、PosterizeEffect 等。
List<ICanvasEffect> effects = new List<ICanvasEffect>();
effects.Add(new GaussianBlurEffect
{
BlurAmount = 4.0f,
BorderMode = EffectBorderMode.Soft,
Optimization = EffectOptimization.Balanced
});
effects.Add(new PosterizeEffect
{
RedValueCount = 3,
GreenValueCount = 3,
BlueValueCount = 3
});
我現在想以抽象的方式設置這些效果的輸入源。 例如,
effects[0].Source = inputBitmap;
effects[1].Source = effects[0];
但是,為了調用 Source 屬性,我必須提供特定類的知識。 例如,
(effects[0] as GaussianBlurEffect).Source = inputBitmap;
(effects[1] as PosterizeEffect).Source = effects[0];
這怎么能以抽象的方式完成,例如,這種方式?
(effects[0] as effects[0].GetType()).Source = inputBitmap;
(effects[1] as effects[1].GetType()).Source = effects[0];
這是 Builder 設計模式的一個很好的例子。 它可能看起來像這樣:
using System.Drawing;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
Bitmap inputBitmap = default;
var canvasBuilder = new CanvasBuilder()
.AddEffect(new CanvasEffect1())
.AddEffect(new CanvasEffect2());
Bitmap bitmap = canvasBuilder.Build(inputBitmap);
}
}
public interface ICanvasBuilder
{
ICanvasBuilder AddEffect(ICanvasEffect effect);
Bitmap Build(Bitmap input);
}
public class CanvasBuilder : ICanvasBuilder
{
private List<ICanvasEffect> _effects = new List<ICanvasEffect>();
public ICanvasBuilder AddEffect(ICanvasEffect effect)
{
_effects.Add(effect);
return this;
}
public Bitmap Build(Bitmap input)
{
foreach (var effect in _effects)
{
effect.ApplyEffect(input);
}
return input;
}
}
public interface ICanvasEffect
{
Bitmap ApplyEffect(Bitmap input);
}
public class CanvasEffect1 : ICanvasEffect
{
public Bitmap ApplyEffect(Bitmap input)
{
//modify bitmap
return input;
}
}
public class CanvasEffect2 : ICanvasEffect
{
public Bitmap ApplyEffect(Bitmap input)
{
//modify bitmap
return input;
}
}
dotnetfiddle: https ://dotnetfiddle.net/W1UBlL
如果GaussianBlurEffect
、 PosterizeEffect
等的作者使用了一些通用接口,其中包括IGraphicsEffectSource Source { get; set; }
IGraphicsEffectSource Source { get; set; }
IGraphicsEffectSource Source { get; set; }
成員。 然后你就可以使用那個界面了。
然而,情況似乎並非如此。
您建議的語法:
(effects[0] as effects[0].GetType()).Source = inputBitmap;
(effects[1] as effects[1].GetType()).Source = effects[0];
當然是不合法的。 與此相對應的允許的事情是:
((dynamic)effects[0]).Source = inputBitmap;
((dynamic)effects[1]).Source = effects[0];
當您使用dynamic
關鍵字時,成員.Source
的綁定被推遲到運行時。 因此 C# 編譯器將生成 CIL 字節碼,它將搜索成員.Source
,給定運行時類型(類似於您嘗試中的.GetType()
),如果找到,將嘗試分配(這將對應調用set
訪問器)。
當然, dynamic
有許多缺點。 通常在編譯 C# 時進行的檢查會dynamic
延遲到運行時,這可能會導致失敗或執行速度變慢。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.