views:

223

answers:

5

So in my COM wrapper I have a property like this:

public string Name
{
    get
    {
        //Call the COM object
        //Work the returned object
       //Return the name.
    }
}

I was doing some reading on read-only properties vs function and was wondering if I should change this to a function instead, something along the lines of:

public string getName
{
       //Call the COM object
       //Work the returned object
       //Return the name.
}

What do you think?

+1  A: 

One factor to take into account: if the code can take a "long" time to run, making it a function makes that slightly more obvious when you're reading the calling code. It's easy to unconsciously assume that name = myObject.Name; is near-instant.

RichieHindle
+1 to counter the -1 this answer got. I don't see any problem with this answer.
Robert Kozak
It's bad design that's why. See my answer
Chad Grant
@Deviant -- you are going down vote crazy. His question doesn't deal with design but in reading code. And he is right, properties are assumed to be near instant when we don't make those assumptions with methods or functions.
Robert Kozak
@Robert I was not commenting on his comment, I was responding to you. I should have directed the comment. His answer is still irrelevant to the question, you shouldn't change a method that does work to a property just because it's "fast".
Chad Grant
+1  A: 

Edit: I'm going to try to lay this all out, because I see this question coming up over and over. Feel free to edit and contribute to my answer.

The standard coding design standard is :

  • Don't do work in properties.

  • Do work in Methods.

Consider this extreme example:

Car c = new Car();
Console.WriteLine( c.Color );

By just writing that code above, would you expect the property Color to be doing this:

public string Color {
  get{
      CarFactory cf = new CarFactory();
      cf.AddWheels();
      cf.AddSteeringWheel();
      cf.AddEngine();
      cf.PaintCar( Color.Red );
      return cf.BuildCar().Color;
  }
}

It's sneaky hidden code that you wouldn't think to be there.

But it would make total sense if the same code where:

Car c = CarFactory.BuildNewCar();
c.Color = Color.Red;

While looking for documentation for you I ran accross: http://msdn.microsoft.com/en-us/library/ms229006.aspx

Which says (rather vaguely): "...properties should not be computationally complex or produce side effects."

It also states "If a getter might throw an exception, consider redesigning the property to be a method."

While it is completely possible that an exception could be thrown while using the COM object in your getter, in this case I do not think it would be good design to wrap it in a method. Especially if the wrapper is temporary and the COM object will be replaced later with managed code. It will keep your API consistent in the future without needing to change it.

Error checking omitted:

public class Wrapper {

    private COMObject _comObj;

    public Wrapper() {
        _comObj = [Create your Com Object here].
    }

    public string Name {
        get
        {
             return _comObj.getName();
        }    
    }
}
Chad Grant
From his question I assumed that "Call the COM object" and "Work the returned object" are much bigger operations than calling getName on the COM object.
Robert Kozak
@Robert Kozak Then it should be broken out into its own method. ComWrapper cw = new ComWrapper(); cw.DoSomeWork(); Console.WriteLine( cw.Name );
Chad Grant
A: 

I like properties better for this case. you could even call a private "getName" function from within the property. Using get and set functions is something to avoid if all possible!

Samuel
+4  A: 

I'd go for:

  • Cheap "get" (+"set") calls: properties
  • Expensive "get" calls or only "set": methods

You see this thinking also back in the .NET Framework.

In you case it should be a method.

taoufik
+2  A: 

It also depends a lot on how big your COM object is and how expensive it is to create. If this is a one time deal you can decide to take the hit once and put the value you need in a backing store accessible via property.

In this case the answer is both use a method and use a property.

public class Foo
{
  private COMObject _ComObject;
  private string _Name;
  private COMObject GetComObject()
  {
    //Construct COMObject here
    // and return it
  }

  public string Name 
  {
    get
    {
      //Lazy load
      if (_ComObject == null)
      {
        _ComObject = GetComObject();
        _Name = _ComObject.getName();
      }
      return _Name;
    }    
  }
}
Robert Kozak
Why on earth would a COM object be so expensive to create that you need to LazyLoad it? You've got much more serious problems going on if you need to resort to this.
Chad Grant
It depends on your performance testing. Lazy loading is a valid technique and there is not enough info to dismiss it as an option. I gave a valid answer and it didn't need to be down voted. That's kinda scummy.
Robert Kozak
+1 because there was no reason to downvote this.
Adam Robinson