C#继承的开放泛型编译



今天我的大脑死了,我想不出一个干净的方法来强迫编译器使用继承进行泛型推理。

想象一下以下4类

型号

public abstract class Model
{
}
public class CodePerfModel : Model
{
}

实体

public abstract class ModelEntity<TModel> where TModel : Model
{
public TModel Model { get; set; }
}
public class CodePerfEntity : ModelEntity<CodePerfModel>
{
}

现在,从逻辑上讲,我应该理所当然地认为,当我通过继承从ModelEntity<>继承的东西(它将指定TModel的类型)时,因为任何从ModelEntity<>继承的类都必须指定它

有没有办法强迫编译器帮我解决这个问题?

例如

如果我现在想使用ModelEntity<>,我必须为它指定一个类型

public class CallerClass<TEntity, TModel>
where TEntity : ModelEntity<TModel>
where TModel : Model
{
}

如何在任何地方都摆脱TModel争论?在编译时仍然可以访问TModel类型?例如,通过基本Model属性。

对我来说,类似于以下内容:

public class CallerClass<TEntity>
where TEntity : ModelEntity<>
{
}

这将是非常有意义的,因为当我称之为时,我只需要说明一下

SomeCall<CodePerfEntity>();

而不是

SomeCall<CodePerfEntity, CodePerfModel>();

这是目前可能的事情吗?

这是否值得为C#6/7筹集资金?

您提到希望在编译时访问TModel,而在派生类时没有显式指定此类型。放弃您的示例,转到更通用的情况,这意味着您希望语义保持不变,但是在声明泛型约束时不希望显式声明类型参数自己的类型参数。

本质上,您是在问为什么没有实现特定的语法sugar功能。

让我们考虑另一个例子:

public class CallerX<A, B> where A : ModelEntity<> where B : ModelEntity<>

根据您问题中的示例,编译器应该分别插入TModel'1TModel'2作为AB的类型参数。假设该功能已实现。这意味着我们已经创建了默认情况,即TModel'1TModel'2是不同的类型,每个类型都有与单个类型匹配的约束。如果我想向TModel'1TModel'2添加更多约束,或者强制它们为相同类型,该怎么办?为什么这种情况如此特殊,以至于它应该有自己的语法?

根据我对C#团队的了解,他们的政策是每个新功能都以"-100分"开头,并且应该非常好才能被考虑(请参见C#的UserVoice)。

总结:

  • 新的语言功能成本高昂,而且增加了复杂性
  • 你要求的是一种隐含的语法,在大多数情况下,它不太可能/不清楚会是想要的情况
  • 开发人员必须学习并理解,作为类型参数约束的开放泛型类型将插入隐藏的匿名额外参数。对我来说,在我没有声明的情况下,将其他类型参数添加到我的类型中是不直观的

相关内容

  • 没有找到相关文章

最新更新