gpt4 book ai didi

c# - 类签名中的通用约束推断

转载 作者:太空宇宙 更新时间:2023-11-03 11:20:11 27 4
gpt4 key购买 nike

在使用 C# 泛型约束时,我对某些要求感到沮丧,我想知道是否有办法解决我的问题。如果不是,我想要解释为什么事情没有按照我希望的方式工作。

这个例子展示了我目前基本上必须做的事情:

public abstract class EntityBase<TID>
where TID : struct, IEquatable<TID>
{ }

public abstract class LogicBase<TEntity, TID>
where TEntity : EntityBase<TID>
where TID : struct, IEquatable<TID>
{ }

public abstract class ServiceBase<TLogic, TEntity, TID>
where TLogic : LogicBase<TEntity, TID>
where TEntity : EntityBase<TID>
where TID : struct, IEquatable<TID>
{ }

// Concrete Examples
public class EgEntity : EntityBase<long> {}
public class EgLogic : LogicBase<EgEntity, long> {}
public class EgService : ServiceBase<EgLogic, EgEntity, long> {}

提案 A 显示了我希望可用的内容(而且我看不出为什么它不能以这种方式工作):

public abstract class EntityBase<TID>
where TID : struct, IEquatable<TID>
{ }

public abstract class LogicBase<TEntity>
where TEntity : EntityBase<?> // why not allow some kind of a "this could be whatever" syntax here ("?"), then infer the constraints on "?" based on the definition of EntityBase<>
{ }

public abstract class ServiceBase<TLogic>
where TLogic : LogicBase<?> // infer the constraints on "?" based on the definition of LogicBase<>
{ }

// Concrete Examples
public class EgEntity : EntityBase<long> {}
public class EgLogic : LogicBase<EgEntity> {}
public class EgService : ServiceBase<EgLogic> {}

提案 B 显示了另一种可能的选择,尽管不如提案 A 有吸引力:

public abstract class EntityBase<TID>
where TID : struct, IEquatable<TID>
{ }

public abstract class LogicBase<TEntity>
where TEntity : EntityBase<TID> // introduce TID here to keep it out of class signature
where TID : struct, IEquatable<TID>
{ }

public abstract class ServiceBase<TLogic>
where TLogic : LogicBase<TEntity> // introduce TEntity here
where TEntity : EntityBase<TID> // introduce TID here
where TID : struct, IEquatable<TID>
{ }

// Concrete Examples
public class EgEntity : EntityBase<long> {}
public class EgLogic : LogicBase<EgEntity> {}
public class EgService : ServiceBase<EgLogic> {}

这两个提议都会最大限度地减少我在创建派生类型时必须指定的类型参数的数量,而提议 A 会消除对一堆冗余约束的需要。

那么,C# 不能/不应该为其中一项提议提供支持有什么原因吗? (或者我是否偶然忽略了该语言的相关现有功能?)

最佳答案

这就是 C# 的基本方式。就允许您对类型施加哪些限制而言,存在一些限制。

一般来说大部分选项为where子句涉及添加此限制将允许您对泛型类中的对象执行某些操作,这取决于所使用的泛型类型(例如:通过告诉它 TIDIEquatable<TID> ,您可以像使用 TID 一样稍后它是一个 IEquatable)。逻辑是,如果您不以任何方式依赖该功能,那么您的类实际上没有理由需要限制(尽管我承认为了清洁起见它可能很好)。

当谈到想要的LogicBase<?> , 一个非常复杂的谜题就你现在可以用这个对象做什么提出了。当你有一个 ServiceBase<TLogic>将您的 TLogic 定义为 LogicBase<?>其中,实际上可以使用 LogicBase 的哪些功能?

如果您希望获得不依赖于知道它是泛型类型的功能的某些子集,那么我要说的是您确实需要定义一个 Interface甚至只是一个 abstract class定义 ServiceBase<TLogic> 的功能不依赖于数据类型 TLogic并克制你的ServiceBase<TLogic>TLogic成为这种新类型。因为这实际上就是您要求应用程序为您推断的内容(表示 LogicBase<?> 的组件的接口(interface),这些组件本身并不依赖于它的通用类型)。

因此,虽然理论上编译器可以以这种方式解释这一点,并在不引用其数据类型的情况下制定出所需的约束强制执行和对象的可用接口(interface),但它在继承的复杂性方面增加了显着的开销设置和我个人的想法是,简单地声明一个接口(interface)将是一种更有条理的方式来处理这个问题。

关于c# - 类签名中的通用约束推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11289227/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com