C#中是否可以扩展一个类,而不仅仅是添加函数而是添加属性。例如:我有一个我依赖的标准DLL库,供应商不想修改它。
在整个代码中我已经广泛使用了DataCell类,现在才意识到我需要为它添加一个额外的属性,因为创建一个继承自这个类的新扩展类看起来不会起作用+很多改写。
DataCell [元数据]
public class DataCell : Message
{
public int Field1;
public int Field2;
public DataCell()
{
..
}
..
}
基本上我想添加一个public int Flags;到这堂课。所以我现在可以做而不重写任何东西,(新的DataCell).Flags = 0x10;
答案 0 :(得分:8)
首先,您应该重新考虑您的方法。 但是如果所有其他方法都失败了,那么你可以排序将属性添加到密封类中:
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);
}
}
}
除非你真的必须,否则请不要这样做。如果有一个更清晰的解决方案,你跳过这个稍微有点hacky的方法,那么这段代码的未来维护者可能会有一些强有力的话。
答案 1 :(得分:7)
嗯,你当然可以扩展一个类,只为它添加字段/属性(尽管我不鼓励根据你的样本使用公共字段)。但是,除非其他代码使用您的新类,否则这些字段将不会存在于创建的对象中。例如,如果其他代码具有:
DataCell cell = new DataCell();
然后不会包含您的Field1
和Field2
字段。
如果基类的每个实例都应该包含这些字段,那么最好不要改进基类而不是扩展它。
如果您想知道是否可以像添加扩展方法一样添加“扩展字段”(例如public static void Foo(this DataCell cell)
),那么不,这是不可能的。
答案 2 :(得分:2)
有两种方法可以向现有类添加属性
添加部分类,但这不适合您,因为部分类应该在同一个程序集中。
在另一个类中继承此类,据我所知,这对您来说是更好的解决方案。
并且你不能像扩展方法那样使用扩展属性。