Leron
Leron

Reputation: 9886

Properly using of the <T> type in generic methods in C#

So my real method is a lot different but I come down to this. It seems I don't fully understand how to handle the generic <T> type when I'm working with generic methods. My understanding is that we use generic methods when we want the same logic to work for different types, but we want the freedom to determine the exact type at run time. So it seems pretty natural to me that when I have a method like this :

internal static void ChangeCode<T>(Entity entity) where T : Entity
{

    T tempEntity;

    if (entity.GetType() == typeof(SomeMoreSpecificEntity))
    {
      tempEntity = new SomeMoreSpecificEntity();
    }
}

However if I try something like this I get an error Can not convert type T to SomeMoreSpecificEntity.

So where am I wrong. Isn't the idea to be able to do exactly this - declare a common type in compile time and cast to more specific type in run time?

Upvotes: 0

Views: 116

Answers (3)

Shengjie YU
Shengjie YU

Reputation: 1444

tempEntity = (T)(object)new SomeMoreSpecificEntity();

T can only cast with object

Upvotes: -3

MarcinJuraszek
MarcinJuraszek

Reputation: 125660

You can't do that. Check following situation:

You have another class named SomeMoreSpecificEntity2 which is declared:

class SomeMoreSpecificEntity2 : Entity
{
}

You call your method ChangeCode<SomeMoreSpecificEntity2>, so T is SomeMoreSpecificEntity2, so tempEntity is SomeMoreSpecificEntity2 as well, but you're trying to assign SomeMoreSpecificEntity to it. That can't work.

You can try changing it to :

internal static void ChangeCode<T>(Entity entity) where T : Entity
{
    Entity tempEntity;

    if (entity.GetType() == typeof(SomeMoreSpecificEntity))
    {
        tempEntity = new SomeMoreSpecificEntity();
    }
}

It compiles.

Upvotes: 4

Jon Skeet
Jon Skeet

Reputation: 1503669

No, the code you're trying to write is broken. For example, suppose I called:

ChangeCode<BananaEntity>(new SomeMoreSpecificEntity());

That would try to assign a reference of type SomeMoreSpecificEntity to a variable of type T, where T is BananaEntity.

It's not clear what you're trying to achieve, but that's why your current code won't compile. Given that you're not actually using T other than for a purpose for which it won't work your current code could be changed to make it a non-generic method, and just declare tempEntity as type Entity. Of course, that might not work for what you really want to do, but as you've only provided the non-working code, that's hard to determine :(

Three points about this line:

if (entity.GetType() == typeof(SomeMoreSpecificEntity))
  • Did you actually mean entity to be of type T rather than type Entity? Currently it can be any entity
  • Did you really want to check the exact type? Normally you'd use is instead of calling GetType and comparing it directly with a type
  • Normally comparing types like this is a sign that you should consider a redesign. It's definitely not generic at this point, as it only copes with types that are hard-coded in it.

Upvotes: 3

Related Questions