I've read the MSDN documentation on C# generic type parameter constraints several times, but I cannot figure out how to do this, or determine if it's even possible.
Say I have a generic base class like this:
public abstract class Entity<TId> { ... }
This abstract base class does not have any type constraints, TId
can be anything -- a struct, class, etc.
Now say I have a generic interface method, and I want to constrain the generic types on the method to the above class:
public interface ICommandEntities
{
void Update<TEntity>(TEntity entity) where TEntity : ?????;
}
I can get this to compile:
public interface ICommandEntities
{
void Update<TEntity, TId>(TEntity entity) where TEntity: Entity<TId>
}
...however then I need to explicitly add both T1 ant T2 generic args when executing the method:
commander.Update<AbcEntity, string>(abcEntity);
If possible, I would like to make the compiler infer everything, so that I can execute the method like this:
commander.Update(abcEntity);
Is this event possible? So far the only way I can get it to work is by adding an empty, non-generic base class above the generic base class and using it as a type constraint on the method:
public abstract Entity {}
public abstract EntityWithId<TId> : Entity { ... }
public interface ICommandEntities
{
void Update<TEntity>(TEntity entity) where TEntity : Entity;
}
commander.Update(abcEntity);
... but then I end up with a pretty useless class that acts as a marker interface. Is that the only way to get away with this type of generic class & interface method design? Or am I missing something here?
After checking that it compiles, I will upgrade it to an answer.
From your question and comments, you want the parameter to be Entity<Something>
. You do not need to use the parametrized types directly as a type, it can be use to parametrize a parameter.
So just do
public void Update(Entity<T1> entity) where ....
The simple option would be to change the signature of ICommandEntities
:
public interface ICommandEntities
{
void Update<TId>(Entity<TId> entity)
}
This effectively gives the same constraint that you're after.
As stated in the comments, you should just make the parameter type BaseClass<T>
class Program
{
static void Main( string[] args )
{
ITest x = new TestClass();
Console.WriteLine( x.GetTypeArgTypeFrom( new BaseClass<int>() ) );
Console.ReadKey();
}
}
public class BaseClass<T>
{
public Type GetTypeArgType()
{
return typeof( T );
}
}
public interface ITest
{
Type GetTypeArgTypeFrom<T>( BaseClass<T> bct );
}
public class TestClass : ITest
{
public Type GetTypeArgTypeFrom<T>( BaseClass<T> bct )
{
return bct.GetTypeArgType();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.