Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Generics function

Tags:

c#

generics

Can someone explain this behavior in Generics?

I have a generic function in C#

protected virtual void LoadFieldDataEditor <T> (ref T control, string strFieldName) where T : Control
{
  //T can be different types of controls inheriting from System.Web.UI.Control
  if (control is TextBox)
  {
   //This line gives an error
   //((TextBox)control).Text = "test";

   //This line works! 
   (control as TextBox).Text = "Test";
  }
}

On a side note, can I use switch case when I am doing a "Control is TextBox" type of checking?

EDIT:

Forgot to add the error message Sorry!

Here you go:

Error   3   Cannot convert type 'T' to 'TextBox'

EDIT:

While we are talking about generics, I have another question. (Wasn't sure If I had to start a new post)

The method has been expanded to include another generic type

protected virtual void LoadFieldDataEditor <T1, T2> (T1 control, T2 objData, string strFieldName) where T1 : Control where T2 : BaseDataType
{
  //I will need to access field1. 
  //I don't know at compile time if this would be SomeType1 or 
 //SomeType2 but all of them inherit from BaseDataType. 

  //Is this possible using generics?
}

public abstract class BaseDataType {}

public class SomeType1 : BaseDataType
{
   string field1;
   string field2;
}
like image 495
DotnetDude Avatar asked Mar 13 '09 14:03

DotnetDude


1 Answers

The rules for what a generic type can be converted to are quite tricky, and occasionally counterintuitive, as in this case. See section 6.2.6 of the C# spec for details. There are places where they could be laxer, and I think this is one of them. You can cast up to object and then down again, but that's ugly.

In this case the better solution would be:

protected virtual void LoadFieldDataEditor <T> (ref T control,
                                                string strFieldName) 
    where T : Control
{
    TextBox textBox = control as TextBox;
    if (textBox != null)
    {
        textBox.Text = "test";
    }
}

Aside from anything else, this only requires a single execution time check instead of two.

For the side note: no, you can't use switch/case on types. (You could get the type name and switch on that, but it would be horrible.)

like image 67
Jon Skeet Avatar answered Sep 18 '22 22:09

Jon Skeet