locked
Overriding .ToString() on predefined class? RRS feed

  • Question

  • Did s ome searching, and I think because what I'm asking is used so little that it's not possible other than writing a complete copey-over function.

    Using .NET 3.5, C# - accessing a webservice that has some defined classes. No source code, so I can't change this class myself.

    One such class, call it the 'User' class, I want to override the .ToString() method. At the moment, .ToString() gives the type name. I want to override it with reporting, say, the users first name and last name.

    I figured it wouldn't work, but I tried something simple, like:

    public class UserOverride : User
    
    {
    
    	public override string ToString()
    
    	{
    
    		return base.FirstName + " " + base.LastName;
    
    	}
    
    }
    
    
    
    // For example:
    
    void Main
    
    {
    
    	User bob = new User();
    
    	UserOverride bobName = (UserOverride)bob;
    
    }
    
    

    That throws an error, obvous, because it can't convert to a narrower class.

    So, my odd question is, is there an easier way - other than creating a function that I feed it a 'User' and it returns a 'UserOverride' - to override just the ToString function of a class?

    Edit: I have searched - and everything I've come across involves either desining/changing the base class, which I can't do here, unfortunately.

    Thanks in advance guys,
    Mike.

    Friday, March 19, 2010 6:03 PM

Answers

  • Mike,

    Instead of making a new object, I would recommend making extension methods to handle the custom formatting:

     

    // Class for extension method(s)
    public static class UserExtensions
    {
        public string PrintName(this User user)
        {
            return user.FirstName + " " + user.LastName;
        }
    }
    
    
    
    // Then, for usage:
    
    void Main()
    {
        User bob = new User()
                      {
                          FirstName = "Bob",
                          LastName = "Someguy"
                      };
    
         // Instead of using ToString(), just use your extension method...
         Console.WriteLine(bob.PrintName());
    }


    Reed Copsey, Jr. - http://reedcopsey.com
    • Marked as answer by Foxtrot_Xray Friday, March 19, 2010 8:05 PM
    Friday, March 19, 2010 6:23 PM

All replies

  • Mike,

    Instead of making a new object, I would recommend making extension methods to handle the custom formatting:

     

    // Class for extension method(s)
    public static class UserExtensions
    {
        public string PrintName(this User user)
        {
            return user.FirstName + " " + user.LastName;
        }
    }
    
    
    
    // Then, for usage:
    
    void Main()
    {
        User bob = new User()
                      {
                          FirstName = "Bob",
                          LastName = "Someguy"
                      };
    
         // Instead of using ToString(), just use your extension method...
         Console.WriteLine(bob.PrintName());
    }


    Reed Copsey, Jr. - http://reedcopsey.com
    • Marked as answer by Foxtrot_Xray Friday, March 19, 2010 8:05 PM
    Friday, March 19, 2010 6:23 PM
  • Hi Reed -

    First off, thanks for that, I just learned something new about the Extensions.

    However, that won't work in my case - reason being (and this is my fault because I forgot to mention why I wanted to do it this way) is that this 'User' class that I'm using, I'd like to add it to certain WPF controls (ComboBox, for example) and allow the combobox code to be able to use my 'overridden' ToString() to return the name instead of the default object's type declaration. (I tried to 'extend' the ToString, but no surprise it didn't work.)

    Thanks,
    Mike.

    Friday, March 19, 2010 7:40 PM
  • Hah, I got it. Odd workaeround, but it worked.

    First - after I posted my last message, I realized I could have then set the ComboBox's "DisplayMemberPath=' attriburte and have it work that way, in conjunction with the Extension class.

    However, I got sidetracked because I remembered the class I was trying to 'modify' was a class that was created by a WebService. (Didn't mention this earlier because I didn't think it was necessary.) However, thiniking about it, since the webservice class technically *IS* defined locally, I jucst added on to it, by: 

    public partial class User
    {
    	public function override ToString()
    	{
    		return this.FirstName + " " + this.LastName;
    	}
    }

    Just re-declaring the class as partial, and inserting the override. Thanks again, offered the push that I needed. -Mike.
    Friday, March 19, 2010 8:05 PM
  • Mike,


    Just one other thing I'll mention -

     

    I'm glad you found an easy way to define your ToString() override.  However, with WPF, if you're working with a class where this isn't possible, you can still easily work around it.

     

    With WPF, when you add a class to a control, like ComboBox, the default behavior is to just use object.ToString(), and place the string into a TextBlock.  That's why you'll often just see class names listed out for a class member.

     

    This behavior is not required, however.  You can also, very easily, make a custom DataTemplate for your class type, and have the ComboBox use the DataTemplate to display your User class.  MSDN has a good example of this for a ListBox.

     

    Basically, all you'd have to do is change your XAML around to have:

    <ComboBox>
       <ComboBox.ItemTemplate>
          <DataTemplate>
             <TextBlock>
                <TextBlock.Text>
                   <MultiBinding  StringFormat="{}{0} {1}">
                      <Binding Path="FirstName"/>
                      <Binding Path="LastName"/>
                   </MultiBinding>
                </TextBlock.Text>
             </TextBlock>
          </DataTemplate>
       </ComboBox.ItemTemplate>
    </ComboBox>

    This works by making your ComboBox display a TextBlock where the text is bound to the item's FirstName and LastName properties directly.  The nice thing here is that you don't have to change your class at all - just your XAML.


    Reed Copsey, Jr. - http://reedcopsey.com
    Friday, March 19, 2010 8:26 PM
  • Hey Reed,

    Ah, that'll work MUCH better! I was under the (incorrect, is seems) assumption that DataTemplates were only for Datasets, but this will work beautifully.

     

    Thanks,
    Mike.

    Friday, March 19, 2010 11:30 PM