【问题标题】:C# how to require a const / static readonly field of generic type parameterC#如何要求泛型类型参数的常量/静态只读字段
【发布时间】:2021-11-19 15:58:42
【问题描述】:

我正在制作一个模拟器,用于模拟太阳系行星和小行星等之间的相互作用。看到我正在编写的很多代码与我为之前模拟石油泄漏的项目编写的代码非常相似,我想使用泛型来重用我的旧代码。我有几个构成模拟器的类,以及一个用于模拟的类(在本例中为天体),它作为泛型类型参数给出。模拟器需要知道它必须为递归公式存储多少帧,这由通用参数决定。

public class Sim<T> where T : IEntity 
{
     readonly int RecursionDepth;     //need to get the value from the class passed as T

     //some more code
}

public interface IEntity 
{
     //cant require a const here, it would be a default implementation instead
     //don't want a int property with get; here as there are no guarantees about the immutability
     //and different instances may have different values.

     //some code
}

将此值设置为模拟中使用的类的常量或静态只读字段是有意义的。但是,这两个选项都不是使用界面所必需的。当然,我可以在接口定义中添加一个属性,但据我所知,我不能要求它是只读的,并且对于类的每个实例都相同。我真的不想求助于它只是传递给系统的随机整数的情况,我必须相信它会成功。

我是否可以设置任何要求,以至少对参数的不变性及其在类的所有实例中的平等性有合理的信心?

【问题讨论】:

    标签: c#


    【解决方案1】:

    在当前的 C# 版本中这是不可能的,但有一个预览功能可以做到这一点 - static abstract members in interfacesproposalgeneric math 预览功能正在积极使用它):

    [RequiresPreviewFeatures]
    public interface IEntity
    {
        static abstract int RecursionDepth { get; }
    }
    
    [RequiresPreviewFeatures]
    class MyEntity : IEntity
    {
        public static int RecursionDepth => 1;
    }
    
    [RequiresPreviewFeatures]
    public class Sim<T> where T : IEntity
    {
        readonly int RecursionDepth = T.RecursionDepth;
    }
    

    要成为早期采用者,您需要安装 nuget System.Runtime.Experimental 并将 set EnablePreviewFeaturestrue 添加到项目设置(也推荐使用最新的框架和 VS 版本):

    <PropertyGroup>
      <EnablePreviewFeatures>true</EnablePreviewFeatures>
    </PropertyGroup>
    

    【讨论】:

    • 感谢您的回答!我期待 .NET 6 的发布。我是否正确理解不可能强制该值是不可变的,因为它可能有一个 set 访问器,或者返回一个可变字段的值?
    • @DimQPire 很高兴有帮助! JFYI.NET 6 已经发布,这是其中的预览功能(即它应该包含在下一个版本中)。至于不可变 - 是的,不可能强制实现不可变(就像我能想到的任何其他实现一样。)
    • 啊,这就是为什么我对 .NET 6 是否发布感到困惑。我有一种感觉 .NET 6 已经发布,但是当你说它是一个预览功能时,我认为我一定是错的。原来我不是。在这种情况下,我希望这个功能在 .NET 7 中完全实现!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-24
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    相关资源
    最近更新 更多