2016-04-25 96 views
-1

我在C#中很新,我需要一些幫助來在我的「Hello World」項目中使用嵌套類。在另一個類中創建和初始化一個類(嵌套)C#

我想創建一個可調用的類,使用class1.subclass1.function(args ...)(創建相關函數組),並且我已經完成了一些工作,但我認爲這是不是最好的辦法。

我的代碼需要在主類和嵌套類(一個數據庫句柄)之間共享一個變量,我在類初始化時使用和參數來完成它。

namespace SameAsPrincipal 
{ 
    public class class1 
    { 
     public SQLiteConnection handle = null; 
     public _subclass1 subclass = null; 

     public class1(string db_file) 
     { 
      handle = new SQLiteConnection(db_file); 
      subclass1 = new _subclass1(handle); 
     } 

     public _subclass1 
     { 
      private SQLiteConnection handle = null; 

      public _subclass1(SQLiteConnection handle) 
      { 
       this.handle = handle; 
      } 

      public void function(args...) 
      { 
       //Do something here 
      } 
     } 
    } 
} 

有人知道更好的方法來創建嵌套的類和共享對象之間的主要和嵌套?

謝謝!

+0

爲了得到你想要的語法,subclass1其方法需要是靜態的,但是,我不確定,如果你能夠訪問class1的屬性,方法等,而無需將它們作爲參數傳遞給subclass1的方法。 – AntiTcb

+0

感謝所有幫助和建議。最後,我創建了一個名爲db_manage的新命名空間,並且在該命名空間中我使用她的方法創建了類。現在就像我想要的:db_manage.class.method(); –

回答

1

沒有更多的情況下,以特定的應用是什麼,這是很難告訴它是否合適。我同意以前的答案,一般說來,單獨的課程更爲正確。您的類B仍然可以在其構造函數中使用DB句柄引用,並且類A甚至可以將它傳遞給它。沒關係。與他們共享變量沒有多大關係,因爲他們都有對同一個DB句柄的引用。

我唯一見過子類/內部類並且不認爲它很奇怪的原因是它只是在父類中使用過的簡單數據對象(雖然它們可能在外部被引用)。例如,如果我創建了鏈表類,我可以選擇讓節點類成爲內部類。對於只是分組功能,常規班應該這樣做。

命名空間也可用於進一步分組。例如,也許我所有的文本操作都位於「MyApp.Text」命名空間中,但隨後又將它們分組爲類似「NumberUtils」,「NameUtils」和「ZipUtils」的類。

+0

謝謝,我很抱歉,英語不是我的主要語言,有時我很難解釋我想要的。該應用程序是用不同的表來管理SQLite數據庫,然後我想用DB inicialization將主類中的所有類組合起來,爲每個表和每個子類上的一些函數創建一個子類。例如:db.music.add(標題,藝術家...),db.music.get(ID),db.film.add(標題,導演...)。 「db」是包含數據庫句柄的主類,音樂和電影是需要訪問主類db hande的嵌套類,而add/get是子類中的函數。 –

1

代替嵌套的對象,創建兩個類(在相同的範圍內),並有一個用其他的,像這樣的:

public class ClassA 
{ 
    public ClassB InstanceOfClassB { get; set; } 

    public ClassA() 
    { 
    InstanceOfClassB = new ClassB(); 
    } 
    //More code here 
} 

public class ClassB 
{ 
    //Code here 
} 
+0

謝謝!!我需要繼續使用參數來傳遞兩個類之間的對象? –

+1

@DanielCarrascoMarín不知道我是否理解這個問題,但是......當一個非原始對象的**實例**交給**時,由**引用**,這意味着如果一個ClassA實例和一個實例ClassC獲得ClassB的相同**實例**,更改ClassB的**實例**上的屬性將可以被ClassA和ClassC的兩個實例看到。這是否回答你的問題? –

+1

@DanielCarrascoMarín如果這不能回答你的問題(或者你不明白我的答案),我很樂意幫助你理解面向對象的設計(這就是我們正在處理的)。我希望SO在這個筆記上有一個很好的一對一聊天功能/下午... –

1

在HelloWorld項目中使用嵌套類?不是一個好兆頭!

我會建議不要使用嵌套類型除非你知道你在做什麼,你有很好的解釋給當記者問。另外還有一些關於.NET Framework指南的建議,它明確建議不要創建public嵌套類。

對於面向對象編程中的數據共享,我們有inheritance功能,這是基於關係/關聯共享數據/成員跨類訪問的最佳方式。

創建的相關功能

由於@Nex Terren建議組(一點點修改),你可以做這樣的事情,在這裏您原理類將作爲工廠和不同類別提供相關功能聚集通過它們的實例

public class PrincipleClass 
{ 
    public ClassB InstanceOfClassB { get; private set; } 
    public ClassA InstanceOfClassA { get; private set; } 

    public PrincipleClass(string db_file) 
    { 
    InstanceOfClassA = new ClassA(new SQLiteConnection(db_file)); 
    InstanceOfClassB = new ClassB(); 
    } 
    //More code here 
} 

public class ClassA 
{ 
    public ClassA(SQLiteConnection handle) 
    { 
    // your code here 
    } 
    public void FunctionOfA1() { } 
    public void FunctionOfA2() { } 
} 

public class ClassB 
{ 
    public void FunctionOfB1() { } 
    public void FunctionOfB2() { } 
} 

現在,你有你的功能組在一起,就像

new PrincipleClass.InstanceOfClassA.FunctionOfA1();
new PrincipleClass.InstanceOfClassB.FunctionOfB1();

注意 - 這也可能不是一個最好的解決方案,但這個方式比使用嵌套類型更好。

+0

謝謝!!,我會試着看看繼承。我需要一些時間來消化關於這方面的微軟信息;) –

+0

它不是特定於微軟,而更多是面向學習對象的方法來設計解決方案。乾杯!! – vendettamit

1

我不明白爲什麼你會想在這種情況下使用嵌套類。你寫它的方式,子類是你所需要的。如果你想要多個方法(或者你稱之爲「函數」),只需添加你的方法。

有沒有一些隱藏的原因,你想在這裏使用嵌套類?作爲一般規則,很少需要嵌套類。

namespace SameAsPrincipal 
{ 
    public class Class1 
    { 
    private SQLiteConnection handle; 

    public Class1(string db_file) 
    { 
     handle = new SQLiteConnection(db_file); 
    } 

    public int AddRecord(Record record) 
    { 
     // use handle to add record and get record Id 
     return record.Id; 
    } 

    public void DeleteRecord(int id) 
    { 
     // Use handle to delete record 
    } 
    } 
} 

當你實例化對象時,你將傳入你的db_file並且連接對象將被創建。然後每個方法都可以在被調用時使用該連接對象。但是,在調用每個方法時創建連接並在操作完成後儘快處置連接通常是更好的主意。當然,這取決於您的業務以及它們是否跨國。大多數情況下,使用「using」塊來實例化連接是使用連接對象的好方法。越早釋放連接越快機器將重新使用該連接,您可以查找連接池以瞭解更多信息。

下面是使用「使用」使用存儲過程添加一個人的實例方法:

public int AddPerson(Person person) 
{ 
    using (var connection = new SQLiteConnection(dbFile)) 
    { 
    connection.Open(); 
    using (var command = new SQLiteCommand("spAddPerson",connection)) 
    { 
     command.CommandType = CommandType.StoredProcedure; 

     var idParameter = new SQLiteParameter("@Id", DbType.Int32); 
     idParameter.Direction = ParameterDirection.Output; 
     command.Parameters.Add(idParameter); 

     command.Parameters.AddWithValue("@FirstName", person.FirstName); 
     command.Parameters.AddWithValue("@LirstName", person.LastName); 

     command.ExecuteNonQuery(); 
    } 
    } 

    return person.Id; 
} 

編輯:至於下面

有幾件事情您的評論:

  1. 使用名稱空間而不是父類來對類進行分組。
  2. 您應該將所有數據庫方法添加到數據庫類並創建用於建模對象的類,而不是子類。
  3. 每個類應該在它自己的文件中
  4. 命名空間部分是.. [] * I.E. Music類具有名稱空間YourApplication.YourProject.Models - 在YourProject項目中,在名爲Music的第一級文件夾中,您將找到一個名爲Music.cs的文件,並在該文件中找到您的音樂課程。這不是要求,編譯器不關心這樣的結構。當你開始獲得更多的代碼時,它只會讓你的生活更輕鬆。

這裏是我講的代碼結構的一個例子(記住每一部分是它自己的文件)

在您的項目稱爲模型的根目錄下創建一個文件夾。在這個模型文件夾中創建一個名爲Music.cs

namespace YourApplication.YourProject.Models 
{ 
    public class Music 
    { 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public double Length { get; set; } 
    public string Artist { get; set; } 
    public string Album { get; set; } 
    } 
} 

在這同一(模型)文件夾中創建一個名爲Film.cs

namespace YourApplication.YourProject.Models 
{ 
    public class Film 
    { 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public double Length { get; set; } 
    public string Director { get; set; } 
    public string[] Actors { get; set; } 
    } 
} 

現在回到項目根(在模型不再文件文件夾)創建一個名爲Persistence的新文件夾。

using System; 
using System.Collections.Generic; 
using System.Data.SQLite; 
using YourApplication.YourProject.Models; 

namespace YourApplication.YourProject.Persistence 
{ 
    public static class DatabaseActions 
    { 
    public static string dbFile; 

    public static Music[] ListMusic() 
    { 
     var musicList = new List<Music>(); 

     // database call to get all music 
     using (var connection = new SQLiteConnection(dbFile)) 
     { 
     connection.Open(); 
     using (var command = new SQLiteCommand("spGetMusic", connection)) 
     { 
      var reader = command.ExecuteReader(); 

      // The try finally blocks are not strictly needed as these will are suppose to be called upon disposal 
      try 
      { 
      // loop through records creating music objects 
      while (reader.Read()) 
      { 
       var music = new Music(); 
       music.Id = reader.GetInt32(0); 
       music.Title = reader.GetString(1); 
       musicList.Add(music); 
      } 
      } 
      finally 
      { 
      reader.Close(); 
      connection.Close(); 
      } 
     } 
     } 
     return musicList.ToArray(); 
    } 

    public static int SaveMusic(Music music) 
    { 
     if (music.Id == 0) 
     { 
     // database stuff - getting the newly created database id 
     } 
     else 
     { 
     // database calls to update record 
     } 

     return music.Id; 
    } 

    public static int SaveFilm(Film film) 
    { 
     if (film.Id == 0) 
     { 
     // database stuff - getting the newly created database id 
     } 
     else 
     { 
     // database calls to update record 
     } 

     return film.Id; 
    } 


    public static Music GetMusic(int id) 
    { 
     var music = new Music(); 

     // database call and setting of values on music 

     return music; 
    } 


    public static Film GetFilm(int id) 
    { 
     var film = new Film(); 

     // database call and setting of values on music 

     return film; 
    } 

    } 
} 

現在終於創建的根文件名爲WorkHarness.cs

using System; 
using YourApplication.YourProject.Persistence; 


namespace YourApplication.YourProject 
{ 
    public class WorkHarness 
    { 

    public void Initialize() 
    { 
     DatabaseActions.dbFile = "your db file"; 
    } 

    public void ShowMusicList() 
    { 
     // list the id and title so user can select by Id 
     foreach (var music in DatabaseActions.ListMusic()) 
     { 
     Console.WriteLine("{0,-10}{1}",music.Id,music.Title); 
     } 
    } 

    public void DisplayMusicItem(int id) 
    { 
     var music = DatabaseActions.GetMusic(id); 

     Console.WriteLine("Title: " + music.Title); 
     Console.WriteLine("Length: " + music.Length); 
     Console.WriteLine("Artist: " + music.Artist); 
     Console.WriteLine("Album: " + music.Album); 
    } 
    } 
} 
+0

感謝您的信息!我必須多想一點,使用嵌套類的唯一原因是創建一個按類別分組的方法樹。例如一個類dbase包含兩個名爲music和film的子類,每個子類都有兩個稱爲add和get的方法。要添加音樂,我想用dbase.music.add()調用它:http://s32.postimg.org/4wykyncp1/example.png –

+1

我在底部添加了一些代碼,它應該與您的場景更好地匹配。希望這會讓你走上更好的道路:) – TwistedStem