C#通过添加属性来扩展类

本文关键字:扩展 属性 添加 | 更新日期: 2023-09-27 18:22:10

在C#中,是否可以不添加函数而是添加属性来扩展类。例如:我有一个标准DLL库,我依赖它,供应商不想修改它。

在整个代码中,我已经广泛使用了DataCell类,直到现在才意识到我需要为它添加一个额外的属性,因为创建一个从这个类继承的新扩展类看起来不太可行+需要大量重写。

DataCell〔元数据〕

public class DataCell : Message
{
public int Field1;
public int Field2;
public DataCell()
{
 ..
} 
..
}

基本上我想添加一个公共的int标志;到这个班。所以我现在可以不用重写任何东西了,(new DataCell)。Flags=0x10;

C#通过添加属性来扩展类

首先,您可能应该重新考虑您的方法。但是,如果所有其他操作都失败了,下面是如何将属性添加到密封类中的方法:

using System;
using System.Runtime.CompilerServices;
namespace DataCellExtender
{
    #region sample 3rd party class
    public class DataCell
    {
        public int Field1;
        public int Field2;
    }
    #endregion
    public static class DataCellExtension
    {
        //ConditionalWeakTable is available in .NET 4.0+
        //if you use an older .NET, you have to create your own CWT implementation (good luck with that!)
        static readonly ConditionalWeakTable<DataCell, IntObject> Flags = new ConditionalWeakTable<DataCell, IntObject>();
        public static int GetFlags(this DataCell dataCell) { return Flags.GetOrCreateValue(dataCell).Value; }
        public static void SetFlags(this DataCell dataCell, int newFlags) { Flags.GetOrCreateValue(dataCell).Value = newFlags; }
        class IntObject
        {
            public int Value;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var dc = new DataCell();
            dc.SetFlags(42);
            var flags = dc.GetFlags();
            Console.WriteLine(flags);
        }
    }
}

除非你真的必须这样做,否则请不要这样做。如果有一个更干净的解决方案,而你跳过了这个稍微有点技巧的方法,那么这个代码的未来维护者可能会对你说一些强有力的话。

当然可以扩展一个类,并且只向其中添加字段/属性(尽管我不建议根据您的示例使用公共字段)。但是,除非其他代码使用您的新类,否则字段将不存在于创建的对象中。例如,如果其他代码具有:

DataCell cell = new DataCell();

将不具有您的Field1Field2字段。

如果基类的每个实例都应该有这些字段,那么你最好弄清楚如何更改基类,而不是扩展它。

如果您想知道是否可以像添加扩展方法一样添加"扩展字段"(例如public static void Foo(this DataCell cell)),那么不可能。

有两种方法可以将属性添加到现有的类中

  1. 添加分部类,但这对您不起作用,因为分部类应该在同一程序集中。

  2. 在另一个类中继承这个类,据我所知,这对您来说是一个更好的解决方案。

不,你不能像使用扩展方法那样使用扩展属性。