C# 如何向属性添加方法?

C# 如何向属性添加方法?,c#,.net,C#,.net,假设我创建了一个具有属性的类: public class User { private string _userID; public string UserID { get { return _userID; } set { _userID = value; } } } 我必须如何处理类和属性才能将方法附加到UserID属性,例如使用“点”语法围绕用户ID生成Xml的方法: 我可以想出如何编写一个方法,将Xml标记放在用户ID的值周围,而我一直

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

public class User
{
   private string _userID;

   public string UserID
   {
      get { return _userID; }
      set { _userID = value; }
   }
}
我必须如何处理类和属性才能将方法附加到UserID属性,例如使用“点”语法围绕用户ID生成Xml的方法:

我可以想出如何编写一个方法,将Xml标记放在用户ID的值周围,而我一直没有想到的是如何使用“点”语法使该方法与属性一起工作


所有这些答案都很有用,感谢大家的贡献。事实上,我标记为“接受”的答案正是我想要的。我很欣赏关于扩展方法的警告性评论(这是我以前从未听说过的),当然,在某些情况下,将扩展方法应用于所有字符串可能会有问题,但在这种情况下,我肯定希望将方法ToXml()应用于类中的所有字符串属性。正是医生要的。我非常熟悉XmlSerialization,但在本例中,由于各种原因,需要避免它

有两种方法:

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

或者,您可以为对象实现。 有博客的极客们有一个很好的教程,如果你运行的是VS2008,他们可以应用到.NET2.0

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

由于扩展方法应用于该类类型的所有对象,因此您需要对扩展方法进行大量加权。(即,我是否希望所有字符串都能调用.ToXML()?)

好吧,对于字符串类型,您不会这样做。您将创建一个新类,该类具有所有必要的字符串处理方法,但也实现了“ToXml()”方法。不幸的是,您无法从字符串类本身派生,因此您必须实现包装器方法或其他一些交付您也需要的字符串处理功能的方式。

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

您可以:

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

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

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

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


    更好的技术是利用.NETXML序列化并将其交给对象。它可以为您发挥XML的魔力。

    在C#3.0中,您基本上有几种方法来完成这项任务,有些更直接,更接近于您希望它的工作方式,有些则更少。首先,让我澄清一下,为什么您可能无法立即了解如何完成这样一件事:

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

    因此,您的选择如下:

  • 将属性的类型更改为自定义类(即
    UserIdentification
    class),并将
    ToXml
    方法添加到此类中。老实说,在大多数情况下,这不是一个很好的解决方案,因为它增加了不必要的复杂性。仅当需要添加与<代码> USERID < /代码> >

  • 有关的多个方法/属性时才考虑它。
  • 只需将
    ToXml
    方法添加到用户类中(并将其称为
    GetIdXmlString
    )。这是一个不错的解决方案,可能是我在C#3.0之前会选择的解决方案(也可能是,视情况而定)

  • 。这是添加到最新版本C#中的一个很好的特性,它允许您通过向现有类和接口添加用特殊语法定义的方法来“扩展”它们。有关更多信息,请参阅链接文章,但您的扩展方法基本上如下所示:

    public static string ToXml(this string str)
    {
        // Code for function goes here.
    }
    
    然后,您可以简单地调用此方法,就好像它实际上属于
    string
    类一样。 但是要小心,因为最后一个方法可能并不总是合适的(因为它可以应用于代码中字符串类型的所有对象)。如果您想编写一个通用的ToXml函数(带重载?),将各种对象转换为您自己的自定义XML格式,那么这就足够了,否则您最好使用第二个建议。helper类是另一种选择,虽然语法稍微不太好,但至少意味着ToXml方法不会出现在所有字符串中


  • 无论如何,希望这能有所帮助……

    我想你可能真的很狡猾,可以通过AOP删除属性,用具有正确方法的代理类替换属性。但即使这样做了,您也可能需要将新属性强制转换到某个接口—实际上是双重转换,即

    IXmlable x = (IXmlable)(object)this.UserId;
    x.ToXml();
    
    这可能会挫败一开始做这件事的意义。但是,嘿,至少你会得到分离的关注,对吗


    说真的,我会选择上面提到的其他更简单的选择。除非你想成为AOP大师,那就是:)

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

    请记住,扩展方法将影响所有字符串,您可能需要也可能不需要。非常好的答案。。。您可能需要添加
    [Serializable]
    public class User
    {
       private string _userID;
    
       [XmlElement()]
       public string UserID
       {
          get { return _userID; }
          set { _userID = value; }
       }
    }
    
    public static string ToXml(this string str)
    {
        // Code for function goes here.
    }
    
    IXmlable x = (IXmlable)(object)this.UserId;
    x.ToXml();