相关疑难解决方法(0)

如何创建不可变类?

我正在创建一个不可变的类.
我已将所有属性标记为只读.

我有一个课程列表.
虽然如果属性是只读的,则可以修改列表.

公开列表的IEnumerable使其不可变.
我想知道为了使一个类不可变而必须遵循的基本规则是什么?

.net c# immutability

108
推荐指数
5
解决办法
5万
查看次数

C#中的不可变对象模式 - 你怎么看?

我在一些项目的过程中开发了一种用于创建不可变(只读)对象和不可变对象图的模式.不可变对象具有100%线程安全的优点,因此可以跨线程重用.在我的工作中,我经常在Web应用程序中使用此模式来配置设置以及我在内存中加载和缓存的其他对象.缓存对象应始终是不可变的,因为您希望保证它们不会意外更改.

现在,您可以轻松地设计不可变对象,如下例所示:

public class SampleElement
{
  private Guid id;
  private string name;

  public SampleElement(Guid id, string name)
  {
    this.id = id;
    this.name = name;
  }

  public Guid Id
  {
    get { return id; }
  }

  public string Name
  {
    get { return name; }
  }
}
Run Code Online (Sandbox Code Playgroud)

这对于简单的类来说很好 - 但是对于更复杂的类,我不喜欢通过构造函数传递所有值的概念.在属性上设置setter是更理想的,构建新对象的代码更容易阅读.

那么如何使用setter创建不可变对象?

好吧,在我的模式中,对象开始是完全可变的,直到你用一个方法调用冻结它们.一旦一个对象被冻结,它将永远保持不变 - 它不能再次变成一个可变对象.如果您需要对象的可变版本,则只需克隆它即可.

好的,现在谈谈一些代码.我在下面的代码片段中试图将模式简化为最简单的形式.IElement是所有不可变对象必须最终实现的基接口.

public interface IElement : ICloneable
{
  bool IsReadOnly { get; }
  void MakeReadOnly();
}
Run Code Online (Sandbox Code Playgroud)

Element类是IElement接口的默认实现:

public abstract class Element : IElement
{
  private bool immutable;

  public …
Run Code Online (Sandbox Code Playgroud)

c# design-patterns functional-programming immutability

47
推荐指数
6
解决办法
2万
查看次数

EF 4.0 - 使用私有字段映射到只读属性

是否可以使用EF 4.0映射以下POCO类?

public class MyClass
{
  private string _myData;

  public MyClass() 
  { }

  public MyClass(string myData)
  {
    _myData = myData;
  }

  public string MyData
  {
    get
    {
      return _myData;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在NHibernate中我认为在映射中使用Access属性是可能的:

<class name="MyClass" table="MyTable">
  <property name="MyData" access="field.camelcase-underscore" column="MyCol" type="string" length="50" />
</class>
Run Code Online (Sandbox Code Playgroud)

我想知道EF 4.0中是否有一些Access等价物?目前,我能够映射类只如果我添加受保护的setter到MyData的属性:

  public string MyData
  {
    get
    {
      return _myData;
    }
    protected set
    {
      _myData = value;
    }
  }
Run Code Online (Sandbox Code Playgroud)

它可以工作,但对于遗留类,它意味着更新所有没有setter的属性.

编辑:

我已经更新了最后一个代码示例,因为它也不适用于私有setter.塞特必须至少受到保护.如果setter是私有的,或者在抛出异常后不存在:

System.InvalidOperationException:映射和元数​​据信息无法进行的EntityType"MyNamespace.MyClass"中找到.

.net mapping entity-framework entity-framework-4

12
推荐指数
2
解决办法
3948
查看次数

WPF ComboBox在一个DataTrigger之后不显示SelectedItem,但在另一个DataTrigger之后显示

因此,我有一个组合框,我想对多组数据重复使用,而不要使用3个单独的组合框。也许这很糟糕,有人可以告诉我。我愿意接受所有想法和建议。我只是想清理一些代码,并认为一个组合框而不是3个组合框更干净。无论如何,当另一个值更改时ItemsSourceSelectedItem所有更改都应该更改,ComboBox's这会提高无法使用的ComboBox的“属性更改”值。最糟糕的部分是,当CurSetpoint.ActLowerModeIsTimerConditiontrue为true时,它总是SelectedItem正确加载,但是从CurSetpoint.ActLowerGseModetrue 变为true时,组合框没有SelectedItem加载。

这是带有问题的ComboBox的XAML。

<ComboBox Grid.Row="1" Grid.Column="1" Margin="5,2" VerticalAlignment="Center" Name="cmbActTimersSetpointsGseVars">
       <ComboBox.Style>
          <Style BasedOn="{StaticResource {x:Type ComboBox}}" TargetType="{x:Type ComboBox}">
             <Style.Triggers>
                <DataTrigger Binding="{Binding Path=CurSetpoint.ActLowerModeIsTimerCondition}" Value="True">
                   <Setter Property="ItemsSource" Value="{Binding TimerInstances}" />
                   <Setter Property="SelectedItem" Value="{Binding CurSetpoint.ActLowerTimerInstance, Mode=TwoWay}" />
                   <Setter Property="DisplayMemberPath" Value="DisplayName"></Setter>
                   <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=CurSetpoint.ActLowerGseMode}" Value="True">
                   <Setter Property="ItemsSource" Value="{Binding EnabledGseVars}" />
                   <Setter Property="SelectedItem" Value="{Binding CurSetpoint.ActLowerGseVar, Mode=TwoWay}" />
                   <Setter Property="DisplayMemberPath" Value="DisplayName"></Setter>
                   <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=CurSetpoint.ActModeIsLogicCondition}" …
Run Code Online (Sandbox Code Playgroud)

c# wpf selecteditem datatrigger itemssource

5
推荐指数
1
解决办法
200
查看次数

使用双缓冲区技术进行并发读写?

我有一个相对简单的案例:

  1. 我的程序将通过 Websockets 接收更新,并将使用这些更新来更新其本地状态。这些更新将非常小(通常 < 1-1000 字节 JSON,因此反序列化 < 1 毫秒),但会非常频繁(高达 ~1000/s)。
  2. 同时,程序将从该本地状态读取/评估并输出其结果。
  3. 这两个任务应该并行运行,并且将在程序的持续时间内运行,即永远不会停止。
  4. 本地状态大小相对较小,因此内存使用量不是一个大问题。

棘手的部分是更新需要“原子地”发生,这样它就不会从本地状态读取,例如,只写入了一半的更新。状态不限于使用原语,并且可以包含任意类 AFAICT atm,因此我无法通过使用Interlocked原子操作之类的简单方法来解决它。我计划在其自己的线程上运行每个任务,因此在本例中总共有两个线程。

为了实现这个目标,我想使用双缓冲区技术,其中:

  1. 它保留状态的两份副本,以便在写入另一份时可以读取一份。
  2. 线程可以通过使用锁来传达它们正在使用哪个副本。即 Writer 线程在写入时锁定副本;读取器线程在完成当前副本后请求访问锁;编写器线程看到读取器线程正在使用它,因此它切换到其他副本。
  3. 写入线程会跟踪在当前副本上完成的状态更新,因此当它切换到另一个副本时,它可以“赶上”。

这是这个想法的总体要点,但实际的实现当然会有点不同。

我试图查找这是否是一个常见的解决方案,但找不到太多信息,所以这让我想知道以下内容:

  1. 它可行吗,还是我错过了什么?
  2. 有更好的方法吗?
  3. 这是一个通用的解决方案吗?如果有的话,通常被称为什么?
  4. (奖励)是否有一个好的资源可供我阅读与此相关的主题?

我几乎觉得我已经走进了一个死胡同,我找不到(因为我不知道要搜索什么)更多的资源和信息来看看这种方法是否“好”。我计划用 .NET C# 编写此内容,但我认为这些技术和解决方案可以转换为任何语言。所有见解均受到赞赏。

c# parallel-processing concurrency multithreading multiprocessing

5
推荐指数
1
解决办法
1235
查看次数

我可以在C#中创建一个包含long和string的列表

我有以下课程:

public abstract class BaseGridViewModel
{
    protected BaseGridViewModel()
    {
        Timer = new List<long>();
    }
    public List<long> Timer { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

要更新我有的计时器:

vm.Timer.Add(sw.ElapsedMilliseconds);
Run Code Online (Sandbox Code Playgroud)

我对列表不太熟悉.我是否可以拥有一个包含long和string的列表,以便我可以执行以下操作:

vm.Timer.Add(sw.ElapsedMilliseconds, "After event 1");
vm.Timer.Add(sw.ElapsedMilliseconds, "After event 2");
Run Code Online (Sandbox Code Playgroud)

c#

3
推荐指数
1
解决办法
69
查看次数