2011-09-26 64 views
2

我有我認爲必須是一個共同的問題。可以說我有一個典型的Person類,我有一個汽車類,它有一個類型的人的場/業主:C#設置屬性/字段值爲none

public class Car 
{ 
    Person owner;   
} 

但有時我想要的車有沒有所有者。處理這個問題的建議方法是什麼? (可編輯:澄清,我的意思是你不能使用Person?owner;)

我可以添加一個布爾字段/屬性:hasOwner,但這似乎相當冗長,所以我覺得像這樣的人創造類人型的靜態成員沒有的:

namespace ConsoleApplication2 
{ 
public class Person 
{ 
    public static Person none; 
    public int age; 

    static Person() 
    { 
     none = new Person(); 
    } 
} 

public class Car 
{ 
    public Person owner; 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Car dumped = new Car(); 
     dumped.owner = Person.none; 
     Console.ReadLine(); 
    } 
} 
} 

這編譯和運行,雖然我還沒有在實際應用中使用它。後來我想我可以做一個通用類與沒有成員像這樣:

namespace ConsoleApplication2 
{ 
public class NoneMember<T> where T : new() 
{ 
    public static T none; 

    static NoneMember() 
    { 
     none = new T(); 
    } 
} 

public class Person: NoneMember<Person> 
{   
} 

public class Car 
{ 
    public Person owner; 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Car dumped = new Car(); 
     dumped.owner = Person.none; 
     if (dumped.owner == Person.none) 
      Console.Write("This car has no owner"); 
     Console.ReadLine(); 
    } 
} 
} 

編譯並運行了,雖然會有一個問題,如果你想繼承表格的人類,與通用和非通用versons。更多有經驗的c#程序員的想法將不勝感激。

編輯:使用null來表示none的問題是您不能將null作爲方法/構造函數參數傳遞。 null表示沒有設置的值,與value不同的是none。

Edit2:我想我得到的異常時,我傳遞null參數。不知道發生了什麼事。我不知道現在是否可以重現錯誤。

+3

爲什麼設置'Person'變量'null'不一個選項? – Oded

+0

同意,可以請你解釋一句「空類型不起作用引用類型已經爲空。」 –

+0

@正好。爲什麼重新發明輪子? –

回答

1

我通常會保持原樣,如果車主爲空,那就意味着這一點 - 它沒有車主。沒有必要複雜化,如果有價值 - 它擁有所有者,否則它沒有(系統所有者已知)。 此策略的例外情況是需要擁有日記數據庫的情況,但在這種情況下,您通常可以擁有版本控制的汽車和所有者,並使用相同的原則。

+0

問題在於您無法將null作爲方法/構造函數參數傳遞。 null表示沒有設置值,這是不同的形式值是none。 –

+2

@Rich Olvier「你不能將null作爲一個方法/構造函數參數」 - 當然可以的。 –

+0

沒有硬性規定'null'表示'未設定值'。最終,'null'的意思是任何你想要的。 如果確實需要分清「值不設置」和「無」,那麼你有幾種選擇 - 例如一個特殊的「空對象」,就像你在上面做的那樣,一個持有者結構相當於'Nullable '或者像組件模型的'XyzSpecified'這樣的邊車屬性。所有這些都有優點和缺點,選擇取決於您的預期用途。 –

1

兩者都是有效的方法。您可能會發現大多數應用程序只是簡單地將屬性保留爲null,並且具有特殊值以指示值類型通常使用空值(TimeSpan.Min等)。

+0

對於可爲空的類型,我認爲監視器值沒有多大意義。 – Oded

1

確實,爲什麼沒有空值適合解決我們的問題。如果所有者爲空,則意味着所有者根本不存在...

0

第一種解決方案是在設計模式中稱爲空對象的東西。 通常情況下,它會做一些不同的事情,您將創建一個從Person繼承的新類。

public class Person 
{ 
    public int age; 
} 

public class NoPerson : Person 
{ 
} 

然後你可以用typeof()聲明

+0

也許有人不喜歡它......我認爲這是一個有效的方法,如果你想強制非空值,無論是理由(我想有人可以帶着理由爲什麼不能有空)。更糟糕的是,這可能是靜態類(因爲只有一個「nobody」:)),您甚至可以擁有表示該情況的數據庫對象(即-1)的硬編碼ID。 –

+0

你仍然會遇到來自Person的繼承問題,不是我順便投了票。 –

0

是的,靜態屬性/領域是有點怪,當你有繼承驗證此。一個框架的例子是EventArgs.Empty字段,國際海事組織將很高興有更多的專業類。

如果你期望繼承Person,並且你希望在整個繼承類中強制實現「這個人就是沒有人」,那麼我的建議就是你將這個概念添加到類本身。

如果你作出這樣的返回true或false一個人是否是「沒有人」還是不虛方法,派生類可用來擴展此檢查,以滿足他們各自的類別的需求:

public class Person 
{ 
    public Person() 
    { 
     // This constructor will create a "nobody" 
    } 

    public Person(string name) 
    { 
     // Proper initialization 
     this.Name = name; 
     _isNobody = false; 
    } 

    public string Name { get; set; } 

    public virtual bool IsNobody 
    { 
     get 
     { 
      return String.IsNullOrEmpty(this.Name) == false; 
     } 
    } 

    // TODO: Maybe override Equals/==/GetHashCode to take IsNobody into account 
} 

一個簡單的例子的重寫Person可以是被定義爲「沒有」,如果任一的基類(人)表示,它是或如果僱員號碼不設置一個Employee:

public class Employee : Person 
{  
    public int EmployeeNumber { get; set; } 
    public override bool IsNobody 
    { 
     return base.IsNobody || EmployeeNumber == -1; 
    } 
} 

你當然可以結合上面的靜態字段上的班,所以對您個人類,你就會有一個

public static readonly Person Nobody = new Person(); 

和派生類(注意使用new改性劑這裏)

new public static readonly Employee Nobody = new Employee(); 

我從來沒有見過這種方法(與'新'修改器)在野外,並會個人是相當不願意使用它,但如果它在您的域是有意義的,它可能是一個替代看看。

0

給予含義null是一種有效的方法,但一般來說,我發現它確實最好有這種情況的「富裕」的支持。

你總是可以建立自己的「空類型」引用類型。你不會有編譯器支持,(例如沒有Person?),但你可以得到非常接近的東西。

例如,看this article from Bart De Smet(尋找Option<T>,在本文的其餘部分是有趣的,但不是你的問題:-)範圍)