在C#中模拟F#`with`关键字

前端之家收集整理的这篇文章主要介绍了在C#中模拟F#`with`关键字前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有没有办法在C#中用关键字模拟F#?我知道它可能不会那么优雅,但我想知道是否有办法处理创建新的不可变数据结构副本.

F#中的记录是detailed here.

这是我正在尝试做的一个例子.我们将通过接口创建“不可变”的数据视图,同时保持具体类的可变性.这让我们可以在本地进行变异(在工作时),然后返回一个不可变的接口.这就是我们在C#中处理不变性的问题.

public interface IThing
{
    double A { get; }
    double B { get; }
}

public class Thing : IThing
{
    double A { get; set; }
    double B { get; set; }
}

但是,当需要对数据进行更改时,来回转换它的类型(或可变性!)是不安全的,将类的每个属性手动转换为新实例也是一种痛苦.如果我们添加一个新的怎么办?我是否必须追踪每次操纵?当我真的只需要以前所拥有的东西时,我不想创造未来的头痛,但是[有些变化].

例:

// ...

IThing item = MethodThatDoesWork();

// Now I want to change it... how? This is ugly and error/change prone:
IThing changed = new Thing {
    A = item.A,B = 1.5
};

// ...

什么是实现这一目标的合理策略?你过去用过什么?

解决方法

由于没有语法糖,我知道你必须要么:

>手工完成(见下文)
>使用一些反射/自动化器(不是这个的粉丝)
>使用一些AOP技术(既不是那些人的粉丝)

至少这是我现在能想到的.

我不认为最后两个是个好主意,因为你带来了大机器来解决一个非常容易的问题.

是的,当你有数千个数据结构时,你可能会重新考虑这个,但如果你只有几个,我就不会使用它.

所以剩下的基本上是智能构造函数和类似的东西 – 这里有一个简单的例子说明你可以做到这一点(请注意,你并不需要所有这些 – 选择) – 它基本上错过了使用null / nullable来查看根据你的需要 – 更好的选择可能是重载或类似选项< T>数据类型,但现在我认为你得到它:

class MyData
{
    private readonly int _intField;
    private readonly string _stringField;

    public MyData(int intField,string stringField)
    {
        _intField = intField;
        _stringField = stringField;
    }

    public MyData With(int? intValue = null,string stringValue = null)
    {
        return new MyData(
            intValue ?? _intField,stringValue ?? _stringField);
    }

    // should obvIoUsly be put into an extension-class of some sort
    public static MyData With(/*this*/ MyData from,int? intValue = null,string stringValue = null)
    {
        return from.With(intValue,stringValue);
    }

    public int IntField
    {
        get { return _intField; }
    }

    public string StringField
    {
        get { return _stringField; }
    }
}

猜你在找的C#相关文章