有没有办法只将一次属性设置为内置机制?

时间:2017-01-27 21:25:24

标签: c# templates properties get set

我从09年5月8日13:29看到Marc Gravell的回答 :

public sealed class WriteOnce<T>
{
    private T value;
    private bool hasValue;
    public override string ToString()
    {
        return hasValue ? Convert.ToString(value) : "";
    }
    public T Value
    {
        get
        {
            if (!hasValue) throw new InvalidOperationException("Value not set");
            return value;
        }
        set
        {
            if (hasValue) throw new InvalidOperationException("Value already set");
            this.value = value;
            this.hasValue = true;
        }
    }
    public T ValueOrDefault { get { return value; } }

    public static implicit operator T(WriteOnce<T> value) { return value.Value; }
}
Then use, for example:

readonly WriteOnce<string> name = new WriteOnce<string>();
public WriteOnce<string> Name { get { return name; } }

但是我无法理解为什么如果它的值为readonly WriteOnce<T>并且它使用只能设置一次的属性private,则会创建Value。 另外我无法理解为什么会创建一个只启用get但不启用set的属性Name

1.您不能设置名称的值,因为它是只读的

2.你不能通过属性设置它的值,因为它只是得到它。

3 个答案:

答案 0 :(得分:1)

你在这里混淆了很多东西。

  1. 只读字段表示只能在构造函数内或通过字段初始值设定项分配。现在WriteOnce是一种引用类型,因此分配仅表示存储在name中的值是对新创建的WriteOnce<string>对象的引用。

    由于您没有更改name.Value = "Hello";的值,因此您无需担心name。另一方面,不允许在构造函数或字段初始值设定项之外使用name = whatever,因为您正在将变量的值更改为新引用,但没有别的。

  2. Name是一个只读属性,具有后备字段name

    只读属性不允许您Name = new WriteOnce<string>(),但Name.Value = "Hello"完全正常。

    无论如何,现在,您只需使用readonly autoproperty并让编译器生成所有管道代码(支持字段):

    public WriteOnce<string> Name { get }
    

答案 1 :(得分:1)

readonly表示只能在构造函数中创建或更改对象。仅将其设为私有而非readonly将允许任何方法来创建新的name字段。所以你可以只设置Value一次,但如果对象不是只读的,你可以完全用新的替换它。

Creatint readonly WriteOnce表示您可以随时设置name值,而不仅仅是在构造函数中,但是一旦设置了值,就无法更改它,也无法将其替换为新的WriteOnce对象。

答案 2 :(得分:0)

您可以将该类重新编写为结构,使其更简单易读。

struct WriteOnce<T>
{
    public T Value { get; }

    public WriteOnce(T input)
    {
        Value = input;
    }

    public static implicit operator WriteOnce<T>(T input)
    {
        return new WriteOnce<T>(input);
    }
}

用法:

WriteOnce<string> name = "test";

您只能更改实例化的值,以便始终知道它的内容。