C # - Determinar tipo de propriedade em tempo de execução
Pergunta
Aqui está o que eu quero fazer:
public [type determined at runtime] ImageToShow
{
get
{
if(this.IsWebContext)
{
return this.GetString();
}
else
{
return this.GetBitmap();
}
}
}
À primeira vista parece simples e factível, se T era o tipo genérico que com instância dessa classe foi criada. Mas o que eu quero fazer é servir uma String ou Bitmap com base na determinação feita dentro da propriedade de imagem de modo que o conhecimento do que para o servidor como imagem está contido dentro da propriedade de imagem e nenhum lugar necessidades mais soubesse sobre isso. Eu posso certamente fazer o tipo de retorno 'objeto' e irá funcionar, mas eu não quero boxe e ineficiência unboxing também não quero reflexão envolvida.
Eu só queria ver com vocês se isso é possível antes de eu desistir dessa ideia.
Solução
Boxing ocorre quando você converte um tipo de valor para um tipo de referência.
int i = 5;
object o = i; // Boxing
Uma vez que você está retornando somente String
ou um Bitmap
, que são os dois tipos de referência, você pode usar objeto sem ter que se preocupar sobre boxe ou unboxing.
Outras dicas
Não seria melhor para o chamador para "conhecer", usando uma propriedade pública
YourClass.IsWebContext
o que esperar?
Em seguida, você seria capaz de usar o tipo genérico T.
Parece que em vez de trabalhar em torno deste você deve considerar um design diferente. Por exemplo a criação de uma classe separada todos juntos por tudo o que vai ser WebContext e implementação de uma interface comum.
Antes de mais nada, retornando tipos de referência como um objeto não é boxe. Boxe só ocorre quando usando um valuetype como um referenceType.
Agora vamos dizer que você está usando o objeto returntype. Depois, você pode verificar se a instância do objeto que é retornado é de um certo tipo usando o operador is
.
object o = myClass.ImageToShow;
if (o is String)
{
// Use as a String
}
else if (o is Bitmap)
{
// Use as a Bitmap
}
Em segundo lugar, eu não recomendo verificar IsWebContext
em cada propriedade. Não faria mais sentido criar uma classe base, e especializar-se dado o ambiente é usado em.
Sim, usar uma 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;}
}
... e em seu código de cliente ....
public IAmImage ImageToShow
{
get
{
return this.IsWebContext?
new StringImage(this.GetString()):
new BitmapImage(this.GetBitmap());
}
}