gpt4 book ai didi

c# - ImmutableArray如何正确使用

转载 作者:行者123 更新时间:2023-12-04 03:42:51 24 4
gpt4 key购买 nike

我正在尝试创建一个永远无法更改的常量值数组。我尝试这样的事情....

public class ColItem
{
public string Header { get; set; } // real header name in ENG/CHI
public string HeaderKey { get; set; } // header identifier
public bool IsFrozen { get; set; } = false;
public bool IsVisible { get; set; } = true;
public int DisplayIdx { get; set; }
}

public struct DatagridSettingDefault
{
public static ImmutableArray<ColItem> DataGrid_MarketPriceTab = ImmutableArray.Create(new ColItem[] {
new ColItem { HeaderKey = "ORDER_ID", IsFrozen = true, DisplayIdx = 0 },
new ColItem { HeaderKey = "PRICE_RENAMEPROMPT", IsFrozen = false, DisplayIdx = 1 },
new ColItem { HeaderKey = "PRICETBL_TRADESTATENO", IsFrozen = false, DisplayIdx = 2 },
new ColItem { HeaderKey = "PRICETBL_BIDQTY", DisplayIdx = 3 },
new ColItem { HeaderKey = "PRICETBL_BID", DisplayIdx = 4 },
new ColItem { HeaderKey = "PRICETBL_ASK", DisplayIdx = 5 },
new ColItem { HeaderKey = "PRICETBL_ASKQTY", DisplayIdx = 6 }
}

然而,这个数组仍然从代码的某个地方(另一个线程)被改变。我怎样才能使数组常量并且在程序的整个生命周期内绝对不能改变?我只需要在编译时初始化它,无论什么引用或其他线程改变它,它都不应该改变。但我的情况一直在变化。

例如,如果我稍后在代码中或通过另一个线程执行类似操作,它会发生变化...

HeaderKey = col.Header.ToString(),
Header = "whatever"
IsFrozen = col.IsFrozen,
IsVisible = true,
DisplayIdx = col.DisplayIndex

我该如何解决?

最佳答案

你不需要ImmutableArray<T> .只需这样做:

  • 更改 DataGrid_MarketPriceTab从可变字段到 getter-only 属性。
  • 我推荐使用 IReadOnlyList<T>而不是 ImmutableArray<T>因为它内置于 .NET 的 BCL 而 ImmutableArray<T>添加对 System.Collections.Immutable 的依赖.
  • 请注意,该属性被内联初始化为 Array。 ( ColItem[] ) 但因为对它的唯一 引用是通过 IReadOnlyList<T>那么不使用反射就无法更改集合。
    • 将其设为 { get; } -only 属性意味着你的类的消费者不能重新分配属性值。
    • 如果您确实需要使用字段(而不是属性),那么将其设置为 static readonly领域。

您还需要制作 ColItem不可变的 - 这可以通过使所有成员属性来完成 { get; }而不是 { get; set; } (并确保它们的类型也是不可变的):

像这样:

// This is an immutable type: properties can only be set in the constructor.
public class ColItem
{
public ColItem(
string headerName, string headerKey, int displayIdx,
bool isFrozen = false, bool isVisible = true
)
{
this.Header = headerName ?? throw new ArgumentNullException(nameof(headerName));
this.HeaderKey = headerKey ?? throw new ArgumentNullException(nameof(headerKey));
this.IsFrozen = isFrozen;
this.IsVisible = isVisible;
this.DisplayIdx = displayIdx;
}

public string Header { get; }
public string HeaderKey { get; }
public bool IsFrozen { get; }
public bool IsVisible { get; }
public int DisplayIdx { get; }
}

public struct DatagridSettingDefault // Why is this a struct and not a static class?
{
public static IReadOnlyList<ColItem> DataGrid_MarketPriceTab { get; } = new[]
{
new ColItem( headerName: "Order Id", headerKey: "ORDER_ID", isFrozen: true, displayIdx: 0 ),
new ColItem( headerName: "Price", headerKey: "PRICE_RENAMEPROMPT", IsFrozen:false, displayIdx:1 ),
new ColItem( headerName: "Foo", headerKey: "PRICETBL_TRADESTATENO", IsFrozen:false, displayIdx:2 ),
new ColItem( headerName: "Bar", headerKey: "PRICETBL_BIDQTY", displayIdx:3 ),
new ColItem( headerName: "Baz", headerKey: "PRICETBL_BID", displayIdx:4 ),
new ColItem( headerName: "Qux", headerKey: "PRICETBL_ASK", displayIdx:5 ),
new ColItem( headerName: "Hmmm", headerKey: "PRICETBL_ASKQTY", displayIdx:6 )
};
}

如果您觉得所有这些都很乏味,我同意!好消息是if you're using C# 9.0 or later (which requires .NET 5, unfortunately) you can use Immutable Record Types , 所以 class ColItem类变为 record ColItem :

public record ColItem(
string Header,
string HeaderKey,
bool IsFrozen = false,
bool IsVisible = true,
int DisplayIdx
);

关于c# - ImmutableArray如何正确使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65661142/

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