views:

145

answers:

5

Here is what I want to do:

public [type determined at runtime] ImageToShow
{
  get
  {
    if(this.IsWebContext)
    {
       return this.GetString();
    }
    else
    {
       return this.GetBitmap();
    } 
  }
}

At first look it seems simple and doable if T was the generic type which with instance of this class was created. But what I want to do is serve a String or Bitmap based on determination made within the Image property so that the knowledge of what to server as Image is contained within the Image property and no place else needs to know about it. I can certainly make the return type 'object' and it will work, but I don't want boxing and unboxing inefficiency neither do I want reflection involved.

I just wanted to check with you guys if this is possible before I give up on this idea.

+1  A: 

Would it not be better for the caller to "know", using a public property

YourClass.IsWebContext

what to expect?

Then you would be able to use the generic type T.

astander
I agree...I'd expose both properties separately and let the caller decide what to do.
JoshBerke
+2  A: 

Boxing occurs when you convert a value type to a reference type.

int i = 5;

object o = i; // Boxing

Since you are returning only String or a Bitmap, which are both reference types, you can use object without having to worry about boxing or unboxing.

João Angelo
+1  A: 

Seems like instead of working around this you should consider a different design. For instance creating a separate class all together for everything that is going to be WebContext and implementing a common interface.

Stan R.
+1  A: 

First of all, returning reference types as an object isn't boxing. Boxing only occurs when using a valuetype as a referencetype.

Now let's say you are using the returntype object. Then you can verify if the object instance that is returned is of a certain type using the is operator.

object o = myClass.ImageToShow;

if (o is String)
{
  // Use as a String
}
else if (o is Bitmap)
{
  // Use as a Bitmap
}

Secondly, I wouldn't recommend checking IsWebContext in every property. It would make more sense to create a base class, and specialize given the environment it is used in.

Yannick M.
A: 

Yes, use an interface.

   public interface IAmImage {}
   public class StringImage: IAmImage
   {
      private string img;
      public string Image { get { return img; } set { img = value; } }
      public StringImage(string image) { img = image;}
   }
   public class BitmapImage: IAmImage
   {
      private Bitmap img;
      public Bitmap Image { get { return img; } set { img = value; } }
      public BitmapImage(Bitmap image) { img = image;}
   }

... and in your client code ....

   public IAmImage ImageToShow 
   {  
       get  
       {    
           return this.IsWebContext?
              new StringImage(this.GetString()):        
              new BitmapImage(this.GetBitmap());    
       }
   }
Charles Bretana
What would the advantage of using this over `object`?
Yannick M.
It's more strongly typed... Only objects of type StringImage or BitmapImage will implement this interface, and so only those concrete types can be returned by this method...
Charles Bretana
I see what you mean, but I would advise against using either technique :-) It would basically defer the type checking to where the instance is used and encourage bad application design.
Yannick M.
Since IAmImage interface doesn't contain any properties making ImageToShow property of type IAmImage doesn't really help. I still have to cast ImageToShow as StringImage or BitmapImage in the calling code. So in that case I might as well return an object and cast it to string or Bitmap in the calling code. The strong type in this case doesn't provide much value IMHO.
codelove
@Yannick, No the type checking is done at Compile time. Becauseit's stromgly typed this enforces the code itself from attempting to construct and return anything that is of type other than the two derived types. And anything that the return value is used in can be typed to accept an instance of this interface as well, guaranteeing that the method must be provided an object of one of these two types.
Charles Bretana
@codelove, see my replies to @Yannick to see "what is accomplished" - But you are right, a cast will always be required in the scenario you present. Although remember, you are just casting the variable, not the object itself. But if the aspects mentioned above are not important to you, (and they may not be), then by all means use object..
Charles Bretana