2012-06-13 56 views
-2

有一個這樣的php代碼(這裏是php函數的一部分)將它轉換爲C#。處理類中全局變量的方法

function jaktDate2() 
{ 
    Global $nameofselectbox,$startYear,$endYear,$year, 
    $startDate,$endDate,$startMounth,$endMounth,$startDay,$endDay; 
    $today = getdate(); 
    $year=$today['year']; 
    $mounth=$today['mon']; 
    $day=$today['mday']; 

我的C#代碼嘗試是這樣的,

public class HuntingDate 
    { 
     public string StartYear; 
     public string EndYear; 
     public string Year; 
     public DateTime StartDate; 
     public DateTime EndDate; 
     public string StartMonth; 
     public string EndMonth; 
     public DateTime StartDay; 
     public DateTime EndDay; 


    } 

我開始這樣..就是這樣正確嗎?接下來我應該做什麼?

+1

任何財產我有點不確定global'的'在* PHP的內部運作* ,但'公共靜態'是* C#*中的正確替代*我相信。並已被指出爲答案,如果可能的話使用屬性而不是字段。 Ex'公共靜態字符串StartMonth {get;設置;}' – flindeberg

回答

1

你定義的類似乎更像值的隨機抓鬥袋,而不是像一個明確的類。所有這些值實際上代表什麼?

public string StartYear; 
public string EndYear; 
public string Year; 
public DateTime StartDate; 
public DateTime EndDate; 
public string StartMonth; 
public string EndMonth; 
public DateTime StartDay; 
public DateTime EndDay; 

例如,是什麼StartDateStartDay之間的區別? StartYearStartMonth是什麼?這個課程實際上是什麼定義?它看起來像是在試圖將DateTime值分解爲組件。你不需要那樣做。一個簡單的DateTime值足夠存儲必要的信息,你可以直接從該值獲得的組件:

public DateTime StartDate; 
public DateTime EndDate; 

如果您需要知道一個月,例如,您可以從價值得到它:

myObject.StartDate.Month; 

要繼續改進班級,您需要使用屬性而不是公共成員。在C#中,這些將如下所示:

public DateTime StartDate { get; set; } 
public DateTime EndDate { get; set; } 

這些被明確稱爲自動實現的屬性。它們是完整屬性的編譯器:

private DateTime _startDate; 
public DateTime StartDate 
{ 
    get { return _startDate; } 
    set { _startDate = value; } 
} 
// repeat for EndDate 

屬性的好處是該類對內部結構的影響較小。如果您需要爲類添加任何邏輯(例如檢查日期的特定邊界,例如確保過去沒有StartDate),則可以將其添加到屬性中,而不會破壞類的二進制兼容性。因此,消費代碼永遠不需要知道差異。例如:

private DateTime _startDate; 
public DateTime StartDate 
{ 
    get { return _startDate; } 
    set 
    { 
     if (value < DateTime.Now) 
      throw new ArgumentException(string.Format("Start Date must not be in the past: {0}", value.ToString())); 
     _startDate = value; 
    } 
} 

通過繼續定義此類的行爲,您可以繼續更進一步。即使將這些屬性暴露出來,仍然使該類更像是「數據結構」而不是「對象」。 (爲了進一步閱讀關於數據/對象的反對稱性,我建議Robert Martin推薦Clean Code。)適當的面向對象設計的目標是讓對象隱藏其數據並公開內部對該數據執行有狀態操作的方法。

例如,如果您需要按天延長EndDate,你可以這樣做:

myObject.EndDate += new TimeSpan(1, 0, 0, 0); 

但是,一個更加面向對象的方法(與堅持「告訴,不要問」校長)將告訴物體本身延長時間,而不是直接告訴其數據延長時間(從而在過程中「詢問」物體的數據,這可能也違反了德米特定律):

myObject.ExtendEndDate(new TimeSpan(1, 0, 0, 0)); 
myObject.ExtendEndDate(new TimeSpan(1, 0, 0, 0)); 

或甚至:

myObject.ExtendEndDateInDays(1); 

你只需要實現在對象上這樣的方法,並且該方法將內部延長EndDate值。

該類本身應該封裝它所表示的概念所需的所有功能。如果絕對必要,它可以爲其內部成員提供公共讀取權限,但從設計角度來看,值得問問自己究竟需要針對對象的數據確定哪種查詢,併爲這些查詢提供更有針對性的方法,而不是直接訪問給班級的數據成員。

1

如果將這些屬性定義爲屬性,效果會更好。 See here for the reason。無論如何,你寫的課程是完全有效的,只是不被認爲是一種好的做法。你可能會添加一個構造函數,也會像php代碼那樣初始化一些值。

+0

你能否提供一些線索?我是初學者到C#? – TechGuy

+0

public string StartYear {get;組; };只是谷歌C#屬性。 – GazTheDestroyer

1

這與屬性:

public class HuntingDate 
{ 
    public string StartYear{ 
     get; 
     set; 
    } 
    public string EndYear{ 
     get; 
     set; 
    } 
} 
1

在c#中沒有辦法像在PHP中那樣做全局。 你可以使用單例或靜態類來做到這一點。

public static class HuntingDate 
{ 
    public static string StartYear { get; set; } 
} 

然後在你的代碼只需

HuntingDate.StartYear = DateTime.Now 

var startYear = HuntingDate.StartYear 
+0

這是AFAIK對問題的唯一直接答案。但可能會有一些關於這個問題的有效性的討論... – flindeberg

0

有在C#中沒有全局變量聲明。因爲它是一種Object Oriented Programming語言。你的情況,你可以聲明static class

public static class HuntingDate 
{ 
    public static string StartYear 
    { 
     get; 
     set; 
    } 
    public static string EndYear 
    { 
     get; 
     set; 
    } 
    // and so on 
} 

,您可以從類名來訪問這些屬性。

HuntingDate.StartDate = DateTime.Now; 
HuntingDate.EndDate = DateTime.Now.AddDays(10); 
+0

adddays是什麼? – TechGuy

+0

@ChathuraRanasinghe只是爲了一個例子,沒有任何正當的理由.....無論如何這種方法是用來添加日期時間對象的日子.. – Talha

2

你可以這樣做:

public int Num { get; set; } 

取而代之的是:

private int _num; 
public int Num { get { return _num; } set { _num = value; } } 

並作爲最後一部分:

DateTime today = DateTime.Now; 
int year = today.Year; 
int month = today.Month; 
int day = today.Day; 

注意today也會有小時,分鐘,秒和毫秒e VEN。如果你只是想的NowDate一部分,或任何其他DateTime對象(又名「修剪」「小罪狀」從小時開始,向下) - 你可以這樣做:

DateTime dateOnly = someDate.Date; 

// someDate: 2.4.2012 10:04:12:0004 
// dateOnly: 2.4.2012 00:00:00:0000 

而且它也像你「重新將需要創建一個從年,月,日DateTime對象,所以:

this.StartDate = new DateTime(startYear, startMonth, startDay); 

編輯

// This gets called the moment you initialize the object 
public HuntingDate() 
{ 
    DateTime today = DateTime.Now; 
    int year = today.Year; 
    int month = today.Month; 
    int day = today.Day; 

    // more logic, to set StartDate and EndDate 
} 

現在從外面你可以做什麼地方:

HuntingDate hd = new HuntingDate(); 
DateTime sd = hd.StartDate; 
DateTime ed = hd.EndDate; 
+1

投票,因爲你更快地鍵入它:) – Kane

+0

@Yorye彌敦道我得到這個錯誤..「字段初始值設定項不能引用非靜態字段,方法或屬性」 – TechGuy

+0

@ expert9在哪一行會給你錯誤? – SimpleVar

2

在.NET中,你不需要有一個私有成員變量的編譯器將在編譯時添加此。

因此,你可以改變

private string _year; 
public string Year 
{ 
    get { return _year;} 
    set { _year = value;} 
} 

到的東西更好看。

public string Year { get; set; } 

要使用日期在.NET中工作,你可以簡單地使用System.DateTime.Now然後訪問諸如System.DateTime.Now.DaySystem.DateTime.Now.Year

+0

向上投票,因爲你提到的自動屬性以及; – SimpleVar

+0

我得到這個錯誤..「字段初始值設定項不能引用非靜態字段,方法或屬性」 – TechGuy