2016-04-25 94 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