2013-07-12 47 views
9

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

已经在整个代码中已经广泛地使用了DataCell类,并且现在才意识到我需要为它添加一个额外的属性,因为创建一个从此类继承的新扩展类只是看起来不会工作+很多重写。

DATACELL [元数据]

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

基本上我想添加一个公众诠释标志;这个班。所以我现在可以不用重写任何东西,(新的DataCell).Flags = 0x10;

+1

你不能有扩展属性,但你可以继承一个类,添加属性 – Sayse

+0

什么你在这种情况下,“延长”意思?你有源代码吗?或者你想使用扩展属性(你不能)?或从DataCell继承好吗? – Tim

+0

通过扩展我的意思是这个类在供应商.dll库中大量使用,我正在使用。创建像ExtDataCell:DataCell不是一个选项,因为我基本上需要重写.dll库。所以我想以某种方式能够做到这一点,所以来自供应商.dll的DataCell可以拥有它没有atm的Flags属性。 (没有修改供应商DLL) –

回答

6

首先,你应该重新考虑你的方法。 但如果一切都失败了,这里是你如何能排序属性添加到一个密封类:

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

这绝对是一个有趣的解决方法。我会首先探索清洁剂的选择,但至少值得考虑。 –

+0

@JonSkeet是的,我忘了明确提及这是多么可怕,而且不应该这样做。我会编辑它。 – dss539

+0

哇这个问题打10k意见。接受这是最好的答案,因为这似乎是我当时需要的。不确定的表现寿。 –

7

那么你当然可以扩展一个类,只添加字段/属性(虽然我不鼓励按照你的样本使用公共字段)。但是,除非其他代码使用您的新类,这些字段将不存在于创建的对象中。例如,如果其他代码有:

DataCell cell = new DataCell(); 

那么不会有你Field1Field2领域。

如果基类的每一个情况下确实应该有这些领域,你会更好的工作如何更改基类而不是扩展。

如果你想知道你是否能作为扩展以同样的方式增加“扩展字段” 方法添加(例如public static void Foo(this DataCell cell))则没有,这是不可能的。

+0

问题是这个类广泛用于供应商提供的另一个类。因此,为每个继承扩展类,需要扩展一堆其他类并重写很多。 好的谢谢 –

+0

@VansS:嗯,我还不清楚基本上基本类是否应该有额外的字段,或谁拥有基类。但是,您不能只将字段添加到您不拥有的类中。 –

+0

@JonSkeet - 你是否介意批评我对这种情况的回答? http://stackoverflow.com/a/17617683/55721 – dss539

2

有两种方法将属性添加到现有类

  1. 添加部分类,但是这不会为你工作,因为局部类应该在同一程序。

  2. 继承此类在一个不同的类,据我所知,这将是一个更好的解决方案。

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

相关问题