Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在另一个泛型基类上添加C#泛型类型约束?_C#_Generics_Type Constraints - Fatal编程技术网

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

如何在另一个泛型基类上添加C#泛型类型约束?,c#,generics,type-constraints,C#,Generics,Type Constraints,我已经多次阅读了有关C#泛型类型参数约束的MSDN文档,但我不知道如何执行此操作,也不确定是否可能 假设我有这样一个通用基类: public abstract class Entity<TId> { ... } commander.Update(abcEntity); 我可以把它编译成: public interface ICommandEntities { void Update<TEntity, TId>(TEntity entity) where TEn

我已经多次阅读了有关C#泛型类型参数约束的MSDN文档,但我不知道如何执行此操作,也不确定是否可能

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

public abstract class Entity<TId> { ... }
commander.Update(abcEntity);
我可以把它编译成:

public interface ICommandEntities
{
    void Update<TEntity, TId>(TEntity entity) where TEntity: Entity<TId>
}
这件事可能吗?到目前为止,我能让它工作的唯一方法是在泛型基类之上添加一个空的非泛型基类,并将其用作方法的类型约束:

commander.Update<AbcEntity, string>(abcEntity);
public abstract Entity {}

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

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

commander.Update(abcEntity);
公共抽象实体{}
公共抽象EntityWithId:实体{…}
公共接口ICommandEntities
{
无效更新(TEntity实体),其中TEntity:实体;
}
指挥官。更新(abcEntity);

。。。但最后我得到了一个相当无用的类,它充当了一个标记接口。这是摆脱这种泛型类和接口方法设计的唯一方法吗?还是我在这里遗漏了什么?

如注释中所述,您应该只将参数类型设置为
BaseClass

类程序
{
静态void Main(字符串[]参数)
{
ITest x=新的TestClass();
WriteLine(x.GetTypeArgTypeFrom(new BaseClass());
Console.ReadKey();
}
}
公共类基类
{
公共类型GetTypeArgType()
{
返回类型(T);
}
}
公共接口测试
{
类型GetTypeArgTypeFrom(基类bct);
}
公共类TestClass:ITest
{
公共类型GetTypeArgTypeFrom(基类bct)
{
返回bct.GetTypeArgType();
}
}

在检查它是否编译后,我会将其升级为答案

根据您的问题和评论,您希望参数为
实体
。您不需要将参数化类型直接用作类型,它可以用于参数化

那就这么做吧

 public void Update(Entity<T1> entity) where ....
公共作废更新(实体),其中。。。。

简单的选择是更改
ICommandEntities的签名

public interface ICommandEntities
{
    void Update<TId>(Entity<TId> entity)
}
公共接口ICommandEntities
{
作废更新(实体)
}

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

voidDOABC(基类impl)
会起作用,但我不确定这是否是您要寻找的。我不明白的是,如果它既不是输入参数也不是返回值,那么使用
T2
。您是否考虑过使接口通用?在更新的示例中,
void doAbc(BaseClass impl)
,我不明白,当你有一个基类的时候,为什么你希望你的更新操作在两个泛型类型上<代码>作废更新(EntityWithId实体)是一个足够好的约束,不是吗
EntityWithId
是一个
实体
,无需对附加类型参数设置泛型约束。。。。好的,我想我现在明白了,这样做,接口方法不需要任何泛型类型约束,如果我使用基类作为方法arg。是吗?你要做的就是定义你想要的参数类型。您需要
实体
,因此只需参数化
X
。不要忘记协方差的问题,也许值得在
中将类型参数标记为
。它可以是
字符串
int
,也可以是
XyzCompositeId
类。我不想在这里使用任何协方差或逆变。我不知道我是否理解你的意思<代码>X
将具有在
实体
参数类型中定义的约束(您提供的代码中没有)。此外,还可以将所需的约束指定为
IEntityCommand.Upload
参数类型。我不知道你是否要求确认没有约束,或者你是否想要定义约束。对,很抱歉造成混淆。我不希望对接口方法有任何附加约束。我只是不希望任何代码能够调用传递非从
实体
派生的类实例的方法。你是对的,我可以让这个方法的X协变。
 public void Update(Entity<T1> entity) where ....
public interface ICommandEntities
{
    void Update<TId>(Entity<TId> entity)
}