如何在另一个通用基类上添加C#泛型类型约束?

时间:2013-11-26 13:28:01

标签: c# generics type-constraints

我已多次阅读有关C#泛型类型参数约束的MSDN文档,但我无法弄清楚如何执行此操作,或确定它是否可行。

假设我有一个像这样的通用基类:

public abstract class Entity<TId> { ... }

这个抽象基类没有任何类型约束,TId可以是任何东西 - 结构,类等。

现在说我有一个通用的接口方法,我想将方法​​的泛型类型约束到上面的类:

public interface ICommandEntities
{
    void Update<TEntity>(TEntity entity) where TEntity : ?????;
}

我可以编译:

public interface ICommandEntities
{
    void Update<TEntity, TId>(TEntity entity) where TEntity: Entity<TId>
}

...然而,我需要在执行方法时显式添加两个T1 ant T2泛型args:

commander.Update<AbcEntity, string>(abcEntity);

如果可能的话,我想让编译器推断出所有内容,这样我就可以执行这样的方法:

commander.Update(abcEntity);

这个活动有可能吗?到目前为止,我能让它工作的唯一方法是在泛型基类之上添加一个空的非泛型基类,并将其用作方法的类型约束:

public abstract Entity {}

public abstract EntityWithId<TId> : Entity { ... }

public interface ICommandEntities
{
    void Update<TEntity>(TEntity entity) where TEntity : Entity;
}

commander.Update(abcEntity);

...但后来我最终得到了一个非常无用的类,它充当了标记界面。这是摆脱这种类型的通用类的唯一方法吗?界面方法设计?或者我在这里遗漏了什么?

3 个答案:

答案 0 :(得分:2)

检查完成后,我会将其升级为答案。

从您的问题和评论中,您希望参数为Entity<Something>。您不需要将参数化类型直接用作类型,它可用于参数化参数。

所以就这样做

 public void Update(Entity<T1> entity) where ....

答案 1 :(得分:2)

简单的选项是更改ICommandEntities的签名:

public interface ICommandEntities
{
    void Update<TId>(Entity<TId> entity)
}

这有效地提供了你所追求的相同约束。

答案 2 :(得分:0)

如评论中所述,您应该只输入参数类型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();
    }
}