我有一段时间是PHP程序员.两天前,我去了一个面试,他们给了我一个在ASP.NET(C#)做的分配.我真的想摆脱php领域的势力,学习一种可以挑战我的体面语言.所以,我有一个问题
是否必须在运行时实例化所有实例?在PHP中,我可以做这样的事情......
class SomeObject {}
$objString = "SomeObject";
$objInstance = new $objString();
Run Code Online (Sandbox Code Playgroud)
我不能在C#中做到这一点,可能因为它是一种编译语言.在C#中,我是否必须创建一个将实例化对象的Factory模式.这也意味着如果我必须在该工厂中实例化10个对象,那么将会有10个if丑陋的陈述.
我用它的Activator::createInstance()方法找到了Activator对象,但是我无法让它工作.还有反思,但这两者(正如我所知)都会对性能产生影响.
那么,有没有办法动态创建对象,或者可能是在C#中,我可以立即创建我的程序将使用的所有对象,这真的很诱人?
编辑
好的,所以让我说我有5个对象用于5个不同的场合.我运行程序,程序评估它需要其中一个对象并实例化它.其他四个从未实例化.我关闭了程序.
第二次,我使用不同的参数运行程序,并创建了这5个对象中的2个,其他三个永远不会出现.
这在PHP中很容易.让我们把Activator和其他工具放在一边,在C#世界中创建所有5个对象是不错的做法,当我知道可能只使用其中一个时?
我不知道我是否理解错了你的问题,但是SomeObject在 C# 中创建给定类的对象非常简单,如下所示:
var obj = new SomeObject();
Run Code Online (Sandbox Code Playgroud)
使用Activator-Class 它应该看起来…… 像以下之一
var obj2 = Activator.CreateInstance(typeof(SomeObject));
var obj3 = Activator.CreateInstance<SomeObject>();`
var someObjType = Type.GetType("SomeObject"); // if you have to use a string
var obj4 = Activator.CreateInstance(someObjType);
Run Code Online (Sandbox Code Playgroud)
请注意,Activator在大多数情况下,不需要使用-Class 来实例化对象。如果您Type在编译时知道类的 ,则第一个示例是标准方法。
更新
关于您的更新,因为我不知道细节,所以我想到的是懒惰的实例化。由于所有内容(包括应用程序的入口点)都是 C# 中的对象,因此您可以使用具有支持字段的属性来解决该问题,如下例所示
class Program
{
// backing fields
private SomeObject obj1;
private SomeObject obj2;
private SomeObject obj3;
private SomeObject obj4;
private SomeObject obj5;
// this way, obj1 only gets instanciated when needed
public SomeObject Obj1
{
get
{
if (obj1 == null)
{
obj1 = new SomeObject();
}
return obj1;
}
}
// same for the other objects
[...]
}
Run Code Online (Sandbox Code Playgroud)
我担心你的对象的内存使用情况,我建议你学习如何正确实现 IDisposable
更新 2
为了提供@Mad Sorcerer 评论中推荐的可能性,您可以使用Lazy-Class来支持字段,这需要您的肩膀一些努力,效果与之前的更新中的效果完全相同。
class Program
{
// Lazy backing fields
private Lazy<SomeObject> obj1 = new Lazy<SomeObject>();
private Lazy<SomeObject> obj2 = new Lazy<SomeObject>();
private Lazy<SomeObject> obj3 = new Lazy<SomeObject>();
private Lazy<SomeObject> obj4 = new Lazy<SomeObject>();
private Lazy<SomeObject> obj5 = new Lazy<SomeObject>();
// this way, obj1 only gets instanciated when needed
public SomeObject Obj1
{
get { return obj1.Value; }
}
// same for the other objects
[...]
}
Run Code Online (Sandbox Code Playgroud)
是的,您可以在C#中动态创建对象.但不像PHP那么容易.
正如你所发现的那样Activator.正确使用它可以正常工作.:)还有直接反射(Activator也基于反射).天真地使用时两者都很慢.
使用该Expression类型,可以缓存用于实例化对象的逻辑.第一次它仍然很慢,但是如果你希望重复创建相同类型的对象,这种方法效果很好(如果你不这样做,那么它的速度很慢Activator并不重要:)).
也就是说,大多数情况下,您不需要像示例中那样动态创建对象.C#中强大的编译时类型检查应该被利用,而不是避免使用.编写实例化在编译时已知类型的对象的代码是最有效的,并且大多数类型安全.
对于那些需要动态行为的相对较少的时间,这是可能的.
| 归档时间: |
|
| 查看次数: |
2443 次 |
| 最近记录: |