如何向属性添加方法?

假设我创建了一个带有属性的类:

public class User { private string _userID; public string UserID { get { return _userID; } set { _userID = value; } } } 

我必须如何处理类和属性才能将方法附加到UserID属性,例如使用“dot”语法围绕用户ID生成Xml的方法:

 User u = new User(); u.UserID = "Mike"; string xml = u.UserID.ToXml(); 

我可以弄清楚如何编写一个方法来将Xml标记放在UserID的值周围,我想要的部分就是如何使用“dot”语法使该方法与属性一起使用。


所有这些答案都很有用,感谢大家的贡献。 事实上,我标记为“被接受”的答案正是我所寻求的。 我很欣赏扩展方法的注意事项(在此之前我从未听说过),当然在某些情况下将扩展方法应用于所有字符串可能会有问题,但在这种情况下我肯定想应用该方法ToXml()到类中的所有字符串属性。 正是医生所要求的。 我对XmlSerialization非常熟悉,但在这种情况下需要避免它出于各种原因。

您必须将该方法添加到属性的类型 。 在这种情况下,UserID是一个字符串,这意味着将其添加到字符串类型并使其可以从所有字符串访问。 我不确定这是个好主意,但如果你真的想要这样做:

 public static class StringUtils { public string ToXmlElement(this string s, string elementName) { return string.Format("<{0}>{1}", elementName, s); } } 

这与您的函数签名不完全匹配,但它更适合附加到更大的字符串类。 唯一的另一种选择是使用不同的底层类型来保存您的UserID,也许是一个隐式转换为字符串的自定义类。

最后,如果您只是尝试以通用方式将用户类编写为Xml,请查看System.Xml.Serialization命名空间。 然后你可以像这样标记你的类并使用XmlSerializer实例来读或写类。

 [Serializable] public class User { private string _userID; [XmlElement()] public string UserID { get { return _userID; } set { _userID = value; } } } 

有两种方法:

您正在操作的对象/值必须具有该方法(例如,当您控制对象定义时)。

 public class UserIDObject { public string ToXML() {} } public class User { private UserIDObject _userID; public UserIDObject UserID { get { return _userID; } set { _userID = value; } } } User u = new User(); u.UserID = = new UserIDObject("Mike"); string xml = u.UserID.ToXml(); 

或者,您可以为对象实现扩展方法(MSDN) 。 Geeks with blogs有一个很好的扩展方法教程,如果你运行的是VS2008,它们可以应用于.NET 2.0。

 public static class MyMethods { public static string ToXML(this string s) { } } 

扩展方法是您想要加权的东西,因为扩展方法适用于该类类型的所有对象。 (IE。我希望所有字符串都能调用.ToXML()吗?)

你可以:

  1. 将_userID更改为自定义类,包装字符串并添加所需的方法。
  2. 为字符串类创建扩展方法 (不推荐)。 这将影响所有字符串对象

嗯,简短的回答是,尽管可以通过扩展方法实现,但您不希望这样做。 这是糟糕的forms,不一定是你想要的。

一种更好的技术将涉及利用.NET XML序列化并将其交给您的对象。 它可以为你做XML魔术。

你基本上有几种方法可以在C#3.0中完成这个任务,有些方法更直接,类似于你希望它如何工作,还有一些更少。 首先,让我澄清为什么你可能不会立即明白如何完成这样的事情:

因为UserID属性是string类型(如您所指定的),所以它的所有成员都被定义,因此仅限于String的成员(至少在传统的面向对象编程[OOP]中)。 这包括当然的方法。 您似乎想要添加ToXml方法,如果没有访问属性的类型(在本例中为System.String ),则无法实现。

所以你的选择如下:

  1. 将属性的类型更改为自定义类(即UserIdentification类),并将ToXml方法添加到此。 在大多数情况下,说实话,这不是一个很好的解决方案,因为它增加了不必要的复 只有在需要添加与UserID相关的多个方法/属性时才考虑它。

  2. 只需将ToXml方法添加到User类(并将其称为GetIdXmlString )。 一个不错的解决方案,可能是我在C#3.0之前选择的(可能仍然,取决于具体情况)。

  3. 扩展方法 。 这是添加到最新版本C#的一个很棒的function,它允许您通过向特定语法定义的方法添加方法来“扩展”现有的类和接口。 有关详细信息,请参阅链接的文章,但您的扩展方法基本上如下所示:

     public static string ToXml(this string str) { // Code for function goes here. } 

    然后,您可以简单地调用此方法,就好像它实际属于string类一样。 但请注意,因为最后一种方法可能并不总是合适的(因为它可以应用于代码中字符串类型的所有对象)。 如果你想编写一个通用的ToXml函数(带有重载?),将各种对象转换成你自己的自定义XML格式,那么公平,否则你可能会更好地使用第二个建议。 辅助类是另一种选择,虽然语法稍微不那么好,但它至少意味着ToXml方法不会出现在所有字符串中。

无论如何,希望这有助于……

而不是有一个字符串,你需要有一个实际支持ToXml()的类

好吧,你不会用String类型做到这一点。 您将创建一个具有所有必需字符串处理方法的新类,但也实现了“ToXml()”方法。 遗憾的是,您无法从字符串类本身派生,因此您必须实现包装器方法或其他一些提供您也想要的字符串处理function的方法。

我想你可能非常狡猾,并通过AOP删除属性,用具有正确方法的代理类替换属性。 但即使你这样做,你可能不得不将你的新属性转换为某个界面 – 实际上是双重投射,即

 IXmlable x = (IXmlable)(object)this.UserId; x.ToXml(); 

这可能会破坏首先做到这一点。 但是嘿 – 至少你会分开担忧,对吧?

说真的,我会选择上面提到的其他更简单的选择。 除非你想成为AOP大师,否则就是这样。 🙂

您可以创建struct UserID值类型,将方法添加到它并在您的类中使用它而不是string