簡體   English   中英

c #readonly對象

[英]c# readonly object

有沒有辦法返回對象的只讀實例?

public class Person
{
    public String FirstName { get; set; }
    public String LastName { get; set; }
}

public class SomeClass
{
    public SomeClass(Person manager)
    {
        if (manager == null)
            throw new ArgumentNullException("manager");

        _manager = manager;
    }

    private readonly Person _manager;
    public Person Manager
    {
        get { return _manager; } //How do I make it readonly period!
    }
}

唯一的方法是通過返回克隆()來執行此操作,以便對克隆而不是原始進行任何更改? 我知道對於Arrays,有一個函數可以將Array作為只讀方式返回。 哦,我知道這是一個參考類型...我還想知道是否有一些隱藏的C#功能來鎖定寫入部分。

我試圖想出一個Generic ReadOnly包裝器類,但是如果沒有做一些昂貴的反射等等,就無法弄清楚如何將屬性作為readonly。

哦,我真的試圖避免創建所有只讀屬性的類的第二個版本。 那時,我不妨返回克隆。

為了避免創建額外的類,您可以將其實現為僅具有只讀屬性的接口IPerson。

public interface IPerson
{
    string FirstName { get; }
    string LastName { get; }
}
public class Person:IPerson
{
    public String FirstName { get; set; }
    public String LastName { get; set; }
}

public class SomeClass
{
public SomeClass(Person manager)
{
    if (manager == null)
        throw new ArgumentNullException("manager");

    _manager = manager;
}

private readonly Person _manager;
public IPerson Manager
{
    get { return _manager; } //How do I make it readonly period!
}
}

您可以將Person類轉換為不可變對象,如下所示。

public class Person 
{ 
    public Person( string firstName, string lastName )
    {
        FirstName = firstName;
        LastName = lastName;
    }

    public String FirstName { get; private set; } 
    public String LastName { get; private set; } 

} 

Castle.DynamicProxy幫助下,您可以在某些條件下凍結對象(使其Castle.DynamicProxy不可變)。 閱讀此博客文章了解詳情。

沒有這樣的功能 - 你已經涵蓋了你的選擇。

克隆它或制作只讀的Person類型。 后一種方法通常是首選的,因為語義更清晰:對於調用者來說,他們不應該(也不能)修改實例是顯而易見的。

這是另一個例子,基於如何在.NET Framework 2.0中實現List.AsReadOnly。 在適當的方法中使用布爾值(IsReadOnly)來防止更新:

public class Person
{
    private string _firstName;
    public string FirstName
    {
        get { return _firstName; }
        set
        {
            if (!IsReadOnly) _firstName = value;
            else throw new AccessViolationException("Object is read-only.");
        }
    }

    private string _lastName;
    public string LastName
    {
        get { return _lastName; }
        set
        {
            if (!IsReadOnly) _lastName = value;
            else throw new AccessViolationException("Object is read-only.");
        }
    }

    internal virtual bool IsReadOnly { get { return false; } }

    public ReadOnlyPerson AsReadOnly()
    {
        return new ReadOnlyPerson(this);
    }

    public class ReadOnlyPerson : Person
    {
        private Person _person;
        internal override bool IsReadOnly { get { return true; } }

        internal ReadOnlyPerson(Person person) // Contructor
        {
            this._person = person;
        }
    }
}

測試它:

static void Main(string[] args)
{
    Person p1 = new Person();
    p1.FirstName = "Joe";
    p1.LastName = "Bloe";
    Console.WriteLine("First = {0} Last = {1}", p.FirstName, p.LastName);

    var p2 = p1.AsReadOnly();
    p2.FirstName = "Josephine"; // AccessViolationException
}

沒有辦法在類外部只讀取對象的所有屬性。 在上面的示例中,除非將Person類中的屬性更改為只讀,否則不能將_manager屬性設置為只讀。

您可以將Person類的屬性的setter設置為internal,這意味着只有與Person相同的程序集中的類才能更改屬性。

或者,如果您將屬性的setter設為private,則只有Person中的代碼才能更改屬性的值。

不。你正在尋找像C ++這樣的東西 - 樣式const ,並且出於各種 原因, C#沒有這個。

但是,匿名類型確實是不可變的。

匿名對象是只讀的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM