簡體   English   中英

如何訪問預定義抽象類的非抽象屬性?

[英]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

如果GaussianBlurEffectPosterizeEffect等的作者使用了一些通用接口,其中包括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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM