不理解 C# 中的对象实例化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/888514/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Not Understanding Object Instantiation in C#
提问by
This post goes to a gap in my understanding of C# classes and why they are preferable to static functions.
这篇文章弥补了我对 C# 类以及为什么它们比静态函数更可取的理解上的一个空白。
I am trying to get a List of objects. Each object in the list represents a record in a table. This would be easy to do in a static function.
我正在尝试获取对象列表。列表中的每个对象代表表中的一条记录。这在静态函数中很容易做到。
Using a class, I've been able to do it as follows:
使用一个类,我已经能够做到如下:
Calling routine:
调用例程:
ListOfBusinesses l = new ListOfBusinesses ();
List<Business> b = l.listBusinesses();
The classes:
课程:
public class Business
{
public string Bupk { get; set; }
public string Bu_name { get; set; }
}
public class ListOfBusinesses
{
public List<Business> listBusinesses()
{
List<Business> businesses = new List<Business>();
businesses.Add(new Business("1", "Business Name 1"));
businesses.Add(new Business("2", "Business Name 2"));
return businesses;
}
}
Couldn't I rewrite the class so that this could be done with one line:
我不能重写这个类,这样就可以用一行来完成:
ListOfBusinesses l = new ListOfBusinesses();
It seems to me like the ListofBusinesses class above is nothing but a static function wrapped in a class which has no properties and is only there for the sake of having a class.
在我看来,上面的 ListofBusinesses 类只不过是一个封装在一个类中的静态函数,该类没有属性,只是为了拥有一个类而存在。
I tried:
我试过:
public class ListOfBusinesses
{
List<Business> businesses;
public List<Business> ListOfBusinesses()
{
List<Business> businesses = new List<Business>();
businesses.Add(new Business("1", "Business Name 1"));
businesses.Add(new Business("2", "Business Name 2"));
return businesses;
}
}
But received the compiler error "member names cannot be the same as there enclosing type". Eg, I tried to use a constructor, but am missing something.
但是收到编译器错误“成员名称不能与封闭类型相同”。例如,我尝试使用构造函数,但遗漏了一些东西。
Any help would enlighten me in an area I have misunderstood for some time.
任何帮助都会在我误解了一段时间的领域启发我。
Mike Thomas
迈克·托马斯
回答by GregC
You are looking for a factory method instead of a constructor.
您正在寻找工厂方法而不是构造函数。
回答by Samir Talwar
Sure. Instead of encapsulating List<Business>
, extend it. Then you just have to add things to it in the constructor.
当然。与其封装List<Business>
,不如扩展它。然后你只需要在构造函数中添加一些东西。
public class ListOfBusinesses : List<Business> {
public ListOfBusinesses() : base() {
Add(new Business("1", "Business Name 1"));
Add(new Business("2", "Business Name 2"));
}
}
To use it:
要使用它:
List<Business> l = new ListOfBusinesses();
回答by Eric Petroelje
Your compiler error is because your class name is "ListOfBusinesses" and the method name is also "ListOfBusinesses". This would be fine if it was a constructor, but since you have a return type on it, C# is thinking you meant it to be a method rather than a constructor.
您的编译器错误是因为您的类名是“ListOfBusinesses”,而方法名也是“ListOfBusinesses”。如果它是一个构造函数,这会很好,但是因为它有一个返回类型,C# 认为你的意思是它是一个方法而不是一个构造函数。
As for getting your list of businesses, why not create a class like this:
至于获取您的企业列表,为什么不创建一个这样的类:
public class BusinessService {
public List<Business> GetBusinesses() {
// Build and return your list of objects here.
}
}
Then to use it:
然后使用它:
BusinessService service = new BusinessService();
List<Business> businesses = service.GetBusinesses();
回答by Jorge Córdoba
The problem is you're using a reserved word (new) used to invoke the constructorof the class.
问题是您使用了用于调用类的构造函数的保留字 (new) 。
The semantic of the constructor is to return an instance of the class which is being created and it follows the rule of having no return value and having the same name of the class.
构造函数的语义是返回正在创建的类的一个实例,它遵循无返回值和类同名的规则。
If it wasn't that way, then, if you do any new MyObject
... how would you (or the compiler for that matter) be supposed to know the returning type?
如果不是那样的话,那么,如果你做任何事情new MyObject
......你(或编译器)应该如何知道返回类型?
回答by mbillard
You're trying to return something different than the class in the constructor
您试图返回与构造函数中的类不同的东西
public class ListOfBusinesses
{
...
public List<Business> ListOfBusinesses()
{
...
You can't specify a return type in a constructor, you need:
您不能在构造函数中指定返回类型,您需要:
public ListOfBusinesses()
{
...
As Mike Thomas said, you should use a factory instead if that's what you want.
正如迈克托马斯所说,如果这是你想要的,你应该改用工厂。
回答by Harper Shelby
Generally speaking, you wouldn't create your ListOfBusinesses class, unless a ListOfBusinesses has some properties that aren't available in a List<Business>. The simplest way of handling this is a static method on the Business class, like so:
一般来说,您不会创建 ListOfBusinesses 类,除非 ListOfBusinesses 具有 List<Business> 中不可用的某些属性。处理这个问题的最简单方法是 Business 类上的静态方法,如下所示:
public class Business
{
//Business class methods/properties/fields
static List<Business> GetList()
{
List<Business> businesses = new List<Business>();
businesses.Add(new Business("1", "Business Name 1"));
businesses.Add(new Business("2", "Business Name 2"));
return businesses;
}
}
While this is the straightforward way, the end result of going down this road is to refactor this method out of the Business class and into an object factory, commonly provided through an ORM framework like NHibernate or Castle Windsor.
虽然这是直接的方法,但走这条路的最终结果是将此方法从业务类中重构到对象工厂中,通常通过像 NHibernate 或 Castle Windsor 这样的 ORM 框架提供。
回答by John Christensen
As people have said before - your syntax isn't right here. ListOfBusiness()
is a constructor and doesn't explicitly return an object. It instead operates on a new instance of ListOfBusiness
and should take care of any creation necessary.
正如人们之前所说 - 你的语法不在这里。ListOfBusiness()
是一个构造函数并且不显式返回一个对象。相反,它在一个新实例上运行,ListOfBusiness
并且应该处理任何必要的创建。
That said - if your method to create the List<Business>
is simple, there's absolutely no reason it should be part of a static method. You could even define an extension method on List that takes an empty list of that and populates it. This is called the Factory pattern, wherein a method or an instance of an object takes charge of creating new instances.
也就是说 - 如果您创建 的方法List<Business>
很简单,则绝对没有理由将其作为静态方法的一部分。你甚至可以在 List 上定义一个扩展方法,它接受一个空列表并填充它。这称为工厂模式,其中一个方法或对象的实例负责创建新实例。
Where you would want to think about extending ListOfBusiness
into an instantiated class is if there are properties or state that needs to be tracked. IF the List<Business>
changes each time it is called, or if you need a place to add new Businesses, the ListOfBusiness
class might be useful for that.
您想要考虑扩展ListOfBusiness
到实例化类的地方是是否有需要跟踪的属性或状态。如果List<Business>
每次调用都会发生变化,或者如果您需要一个地方来添加新的业务,ListOfBusiness
该类可能对此有用。
回答by lc.
I think you're mixing up the concepts of a static function, a constructor, and a factory method.
我认为您混淆了静态函数、构造函数和工厂方法的概念。
Static Function
静态函数
Definition
定义
This is a method which does not have access (and is not associated with) a this
instance of a class.
这是一种无法访问(也不关联)this
类实例的方法。
Example
例子
public class BusinessHelper
{
public static List<Business> ListBusinesses()
{
List<Business> businesses = new List<Business>();
businesses.Add(new Business("1", "Business Name 1"));
businesses.Add(new Business("2", "Business Name 2"));
return businesses;
}
}
Usage
用法
Call a static method with the class name, not an instance of the class.
使用类名调用静态方法,而不是类的实例。
List<Business> businesses = BusinessHelper.ListBusinesses();
Constructor: This is a method which creates the this
instance of a class. It does not have a return value and is invoked when an object is instantiated.
构造函数:这是一种创建this
类实例的方法。它没有返回值,并在实例化对象时调用。
Example
例子
public class BusinessList
{
public List<Business> TheList;
public BusinessList()
{
TheList = new List<Business>();
TheList.Add(new Business("1", "Business Name 1"));
TheList.Add(new Business("2", "Business Name 2"));
}
}
Usage
用法
Create a new instance of the object.
创建对象的新实例。
BusinessList myBusinessList = new BusinessList();
businesses = myBusinessList.TheList;
Factory Method
工厂方法
Definition
定义
This is a method that creates an instance of an object, instantiates it in some way, and returns a reference to it.
这是一种创建对象实例、以某种方式实例化并返回对它的引用的方法。
Example
例子
public class BusinessList
{
public List<Business> TheList;
public static BusinessList BusinessListWithTwoCompanies()
{
BusinessList instance = new BusinessList();
businesses = new List<Business>();
businesses.Add(new Business("1", "Business Name 1"));
businesses.Add(new Business("2", "Business Name 2"));
return instance;
}
}
Usage
用法
Call the factory method instead ofcreating a new object.
调用工厂方法而不是创建新对象。
BusinessList myBusinessList = BusinessList.BusinessListWithTwoCompanies();
businesses = myBusinessList.TheList;
Two things to additionally note:
另外要注意两点:
You declare a
businesses
field, but proceed to instantiate anothervariable calledbusinesses
in yourListOfBusinesses()
method and return it. Nothing will happen to thebusinesses
field. Be careful with variable scoping.You cannot have a member (field, property, or method) with the same name as the class. This is reserved for the constructor, which has no return type (see above). This is why you are getting the compiler error.
您声明了一个
businesses
字段,但继续实例化在您的方法中调用的另一个变量并返回它。球场上什么都不会发生。小心变量作用域。businesses
ListOfBusinesses()
businesses
您不能拥有与类同名的成员(字段、属性或方法)。这是为构造函数保留的,它没有返回类型(见上文)。这就是您收到编译器错误的原因。
回答by ChrisBD
Object instantiation is fundamentally the same for all OO languages. Use of classes rather than static functions allows for much more flexibility and ultimately less coding, especially when keeping track of many similar items.
所有 OO 语言的对象实例化基本上都是一样的。使用类而不是静态函数可以提供更大的灵活性并最终减少编码,尤其是在跟踪许多类似项目时。
Think of books and libraries.
想想书籍和图书馆。
If you have the book as an object class then you can instantiate it to create lots of books and store them in your library. Every book that you have instatiated is unique. If you have made no changes to it then each instantiated book appears to be a copy of the original (although at a low level each book has a unique serial number). It has the same cover, number of pages and content, BUT you can easily write your name in one copy thus making it different to the rest.
如果您将这本书作为对象类,那么您可以将其实例化以创建大量书籍并将它们存储在您的图书馆中。您创建的每一本书都是独一无二的。如果您没有对其进行任何更改,那么每本实例化的书籍似乎都是原始书籍的副本(尽管在较低级别每本书都有一个唯一的序列号)。它具有相同的封面、页数和内容,但您可以轻松地将您的名字写在一份副本中,从而使其与其他副本不同。
If you made the book a static then although you can't create individual copies, instead you are looking at the same book, but from different points of view. If you write your name in it then your name appears in every view of the book.
如果您将这本书设为静态,那么虽然您无法创建单独的副本,但您正在查看同一本书,但从不同的角度来看。如果你在里面写下你的名字,那么你的名字就会出现在这本书的每个视图中。
I wont post any code as whilst I've been typing this plenty of others have posted code samples for your business objects.
我不会发布任何代码,因为我一直在输入这个,很多其他人已经发布了您的业务对象的代码示例。
回答by Andrea Balducci
If i'm not wrong you want to access a db and retrieve a list of objects with a single line call.
如果我没错,您想访问一个数据库并通过单行调用检索对象列表。
First of all you need a DAO class that encapsulates the db access and expose a List method. Inside the DAO you can use NHibernate, Linq2XXX or whatever you want (sample)
首先,您需要一个封装了 db 访问并公开 List 方法的 DAO 类。在 DAO 中,您可以使用 NHibernate、Linq2XXX 或任何您想要的(示例)
public class BusinessItem
{
public string Code { get; set; }
public string Description { get; set; }
}
public class BusinessItemsDAO
{
...
public List<BusinessItem> List()
{
// fake... should retrieve from db
var list = new List<BusinessItem>();
// returs the list
return list;
}
...
}
your client code could just call
您的客户端代码可以调用
var listOfBusinessItems = new BusinessItemsDAO().List();
returning an IQueryable instead a List could help if you are Linq enabled.
如果您启用了 Linq,则返回 IQueryable 而不是 List 可能会有所帮助。