Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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# Net中不可变类型的示例_C#_.net_Vb.net_Immutability - Fatal编程技术网

C# Net中不可变类型的示例

C# Net中不可变类型的示例,c#,.net,vb.net,immutability,C#,.net,Vb.net,Immutability,我们知道不变性的概念,但需要知道的是除了 串 日期时间 还有更多吗?TimeSpan,或者现代类型的家庭元组元组是不可变的,因为它的实现支持.NET中的函数式语言(F#F.e.) 当然,您可以根据自己的意愿使自己的类和结构可变或不可变。不可变类型(也称为值对象)在多线程编程、函数编程和清除代码中非常有用 要使类或结构不可变,只需删除所有公共/受保护/内部setter;最好用readonly关键字声明所有字段。下面是框架类库中的不可变类型列表。(请随意扩展!) 系统… 所有基本值类型:(注意

我们知道不变性的概念,但需要知道的是除了

  • 日期时间

还有更多吗?

TimeSpan
,或者现代类型的家庭
元组<代码>元组
是不可变的,因为它的实现支持.NET中的函数式语言(F#F.e.)

当然,您可以根据自己的意愿使自己的类和结构可变或不可变。不可变类型(也称为值对象)在多线程编程、函数编程和清除代码中非常有用


要使类或结构不可变,只需删除所有公共/受保护/内部setter;最好用
readonly
关键字声明所有字段。

下面是框架类库中的不可变类型列表。(请随意扩展!)

系统…
  • 所有基本值类型:(注意:!)
    • Byte
      SByte
    • Int16
      UInt16
    • Int32
      UInt32
    • Int64
      UInt64
    • IntPtr
    • Single
    • Double
  • Decimal
  • 编译器创建的所有匿名类型(
    new{…}
    在C#中,
    new With{…}
    在VB.NET中)(错误原因有两个:这些类型不在FCL中,显然VB.NET类型是可变的。)
  • 所有枚举类型(
    enum
    enum
  • 所有委托类型。(请参阅。虽然委托似乎是可变的(因为您可以执行
    obj.PropertyChanged+=callback
    ,但实际上是
    obj.PropertyChanged
    引用发生了变化,指向新构造的委托实例;原始委托实例保持不变。)
  • DateTime
    TimeSpan
    (在中提到)和
    DateTimeOffset
  • DBNull
  • Guid
  • Nullable
  • String
  • .NET4引入的
    Tuple
    类型(在中提到)
  • Uri
  • 版本
  • Void
System.Linq….
  • 查找

我不确定您是在寻找.NET中的公共不可变类型还是完全不可变的类型。此外,您想只考虑.NET中的公共类型?更深层次的问题是定义什么形式的不可变。只有

public readonly int[] Numbers;
使其不可更改?数字本身不能更改,但其内容可以更改。你明白了

无论如何,您可以通过编程方式检查自己。对于更深层次的嵌套检查,您将需要递归(我在这里不会这样做)

加载所有要检查的程序集,并执行类似操作(未测试)

即使这样,也不足以找到集合类型的不可变性。一些不可变集合类型(虽然不是默认.NET core的一部分)可以在此处找到:


一些值得注意的不可变因素:

  • 一些类类型,如
    String
    Tuple
    ,匿名类型
  • 大多数结构(值得注意的例外包括大多数枚举数)
  • 列举
  • 代表
  • 不可变的集合类型,如

    ImmutableArray(预发布版本)

    不可变字典

    不可变排序字典

    不可变哈希集

    不可变列表

    不可变队列

    不可变排序集

    不可变粘性


    • 来自mscorlib的一些示例:

      • 所有的基本类型
      • 列举
      • decimal
      • (U)IntPtr
      • DateTime
        DateTimeOffset
        TimeSpan
      • KeyValuePair
        -相反,
        DictionaryEntry
        不是不可变的
      • Tuple
      • (多播)委托
        -与字符串类似,在更改新实例时始终返回新实例
      • Guid
      • 版本
      有趣的是,
      string
      实际上并不是不可变的;但是,我们可以将其视为“实际上不可变”类型,这意味着string实例的内容不能通过公共方式更改(至少在安全上下文中)但是它有一个
      wstrcpy
      内部方法,它被
      StringBuilder
      类用来操作字符串实例。

      使用.NET 5和新的C#9.0版本,现在几乎每个对象都可以是不可变的(或者在属性中包含不可变的状态)


      这里有更多信息:

      大多数人只知道字符串,更不用说DateTime了。因此,我提出了一个问题来帮助我们的开发者社区。Re:创建一个不可变类型列表以便于参考。这是个好主意,但也许最好只有一个(社区wiki)答案是每个人都可以扩展;否则,我们最终会得到大量答案,其中大多数答案可能只列出框架中不可变类型的一小部分。要清楚的是,仅仅因为值类型碰巧是不可变的,并不意味着所有不可变对象都是值类型……一种在不改变其内部状态的类型从外部进行OSBerable操作可能是不可变的:例如,一个昂贵的属性延迟计算一次,然后缓存结果。不可变的类型不一定意味着
      只读
      字段。@Claies,是的,当然。我的文本中的值对象是一个模式名,而不是.NET值类型。这个模式由f.e.@InBetween,y描述你是对的。然而,这种可能性表明这个类至少有两种责任。这违反了OO设计。因此,你可以这样做,但你不应该这样做。@MarkShevchenko:)我写了评论后,开始对它进行更多思考,最后我问了很多,因为我不确定正确的answ是什么
      var immutables = AppDomain.CurrentDomain
                      .GetAssemblies()
                      .SelectMany(t => t.GetTypes())
                      .Where(t => t
                                 .GetProperties(your binding flags depending on your definition)
                                 .All(p => !p.CanWrite) 
                               && t
                                 .GetFields(your binding flags depending on your definition)
                                 .All(f => f.IsInitOnly)
                      .ToList();