关于oop:C#通过添加属性来扩展类

C# Extend class by adding properties

本问题已经有最佳答案,请猛点这里访问。

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

在整个代码中,我已经广泛地使用了Datacell类,并且直到现在才意识到我需要向它添加一个额外的属性,因为创建一个从这个类继承的新扩展类看起来并不能工作,而且需要大量重写。

数据单元[元数据]

1
2
3
4
5
6
7
8
9
10
public class DataCell : Message
{
public int Field1;
public int Field2;
public DataCell()
{
 ..
}
..
}

基本上,我想向这个类添加一个公共int标志。所以我现在可以不用重写任何东西了,(新的datacell).flags=0x10;


首先,你应该重新考虑一下你的方法。但是如果所有其他方法都失败了,下面是如何向密封类添加属性的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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);
        }
    }
}

请不要这样做,除非你真的必须这样做。如果您跳过了一个更干净的解决方案,支持这种稍微有点黑客的方法,那么未来的代码维护人员可能会对您有一些有力的支持。


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

1
DataCell cell = new DataCell();

那就没有你的Field1Field2字段了。

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

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


向现有类添加属性有两种方法

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

  • 在另一个类中继承这个类,据我所知,这将是一个更好的解决方案。

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