【问题标题】:C# Inherited Open Generics CompileC#继承开放泛型编译
【发布时间】:2015-04-28 22:26:45
【问题描述】:

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

想象以下 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&lt;&gt; 继承的东西(它将指定 TModel 的类型)时,因为任何从 ModelEntity&lt;&gt; 继承的类都必须指定它。

是否有强制编译器为我解决这个问题?

例如

如果我目前想使用ModelEntity&lt;&gt;,我必须为其指定一个类型。如:

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 提出吗?

【问题讨论】:

  • "现在对我来说,逻辑上我应该理所当然地认为,当我通过继承从 ModelEntity 继承某些东西时(它将指定 TModel 的类型),因为任何继承自 ModelEntity 的类将不得不指定它。”句子不解析。
  • @spender 我来自英国(或至少从 5 岁开始)。 TBH 我不觉得这个词有冒犯性,但这可能只是因为我有一群朋友。但我可以看到你来自哪里,所以我改变了它。
  • @MichalCiechan 我也是,是的,我也有不好的陪伴;)但some people 确实对此感到不安。
  • @spender 哈哈@链接哈哈

标签: c# generics types compilation open-generics


【解决方案1】:

您提到您希望在编译时访问TModel,而不是在派生类时明确指定此类型。放开你的例子,转向更一般的情况,这意味着你希望语义保持不变,但是你不想在声明泛型约束时显式声明类型参数自己的类型参数。

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

让我们考虑另一个例子:

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

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

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

总结一下:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-23
    • 2011-08-20
    • 2015-05-12
    • 1970-01-01
    相关资源
    最近更新 更多