You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core7 C#:无共同基类时修改不同对象的同属性

在.NET Core 7中修改无共同基类对象的Font属性(编译时校验)

方法一:静态抽象接口成员(原生编译时检查,.NET 7+专属)

这种方法无需修改现有类型,通过泛型约束让编译器直接校验类型是否具备Font属性。

  1. 定义带静态抽象成员的泛型接口,用于约束类型的Font属性访问:
public interface IHasFont<T>
{
    static abstract Font GetFont(T instance);
    static abstract void SetFont(T instance, Font value);
}
  1. 为每个具备Font属性的类型实现该接口(无需修改原类型代码,在自己的项目中实现即可):
// 为WinForms Button实现接口
public static class ButtonFontAccessor : IHasFont<Button>
{
    public static Font GetFont(Button instance) => instance.Font;
    public static void SetFont(Button instance, Font value) => instance.Font = value;
}

// 为WinForms Label实现接口
public static class LabelFontAccessor : IHasFont<Label>
{
    public static Font GetFont(Label instance) => instance.Font;
    public static void SetFont(Label instance, Font value) => instance.Font = value;
}
  1. 编写泛型缩放方法,通过接口约束实现编译时校验:
private void RescaleFont<T>(T controlWithFont, double scale) where T : IHasFont<T>
{
    var originalFont = IHasFont<T>.GetFont(controlWithFont);
    var newFont = new Font(originalFont.FontFamily, originalFont.Size * scale, originalFont.Style);
    IHasFont<T>.SetFont(controlWithFont, newFont);
}

调用示例:

var button = new Button();
RescaleFont(button, 1.5); // 编译通过

var invalidObj = new object();
RescaleFont(invalidObj, 1.5); // 编译错误:object未实现IHasFont<object>

方法二:接口+包装类(兼容更早版本,编译时间接校验)

通过包装类将不同类型适配到统一接口,结合扩展方法实现编译时校验(无对应扩展方法则编译报错)。

  1. 定义统一接口:
public interface IHasFont
{
    Font Font { get; set; }
}
  1. 编写泛型包装类,用于适配不同类型的Font属性:
public class FontWrapper<T> : IHasFont where T : class
{
    private readonly T _instance;
    private readonly Func<T, Font> _fontGetter;
    private readonly Action<T, Font> _fontSetter;

    public FontWrapper(T instance, Func<T, Font> getter, Action<T, Font> setter)
    {
        _instance = instance;
        _fontGetter = getter;
        _fontSetter = setter;
    }

    public Font Font
    {
        get => _fontGetter(_instance);
        set => _fontSetter(_instance, value);
    }
}
  1. 为每个具备Font属性的类型编写扩展方法,生成包装实例:
public static class FontExtensions
{
    public static IHasFont AsHasFont(this Button button)
    {
        return new FontWrapper<Button>(button, b => b.Font, (b, f) => b.Font = f);
    }

    public static IHasFont AsHasFont(this Label label)
    {
        return new FontWrapper<Label>(label, l => l.Font, (l, f) => l.Font = f);
    }

    // 其他具备Font属性的类型同理添加扩展
}
  1. 编写缩放方法,接收接口实例:
private void RescaleFont(IHasFont controlWithFont, double scale)
{
    var originalFont = controlWithFont.Font;
    var newFont = new Font(originalFont.FontFamily, originalFont.Size * scale, originalFont.Style);
    controlWithFont.Font = newFont;
}

调用示例:

var button = new Button();
RescaleFont(button.AsHasFont(), 1.5); // 编译通过

var invalidObj = new object();
RescaleFont(invalidObj.AsHasFont(), 1.5); // 编译错误:object无AsHasFont扩展方法

方法三:动态类型(不推荐,仅运行时校验)

如果无需编译时校验,可使用dynamic类型,但仅会在运行时抛出异常,不符合需求:

private void RescaleFont(dynamic controlWithFont, double scale)
{
    var originalFont = controlWithFont.Font;
    var newFont = new Font(originalFont.FontFamily, originalFont.Size * scale, originalFont.Style);
    controlWithFont.Font = newFont;
}

内容的提问来源于stack exchange,提问作者Daniel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 14:10:27