我有一整套与一个类实例交互的方法。现在我把它初始化在页面加载(从会话中转换)。代码与此类似(为了示例而简化):
protected void Page_Load(object sender, EventArgs e)
{
if(!isPostBack)
{
MyClass myClass = (MyClass)Session["myClass"];
myMethod1(myClass);
myMethod1(myClass);
}
}
private void myMethod1(MyClass class)
{
}
private void myMethod2(MyClass class)
{
}
这是正确的方法,还是最好在页面后面的类中声明它“globaly”而不是将它从方法传递给方法。
修改
我想我真正的问题是:将它传递给方法是否存在性能缺陷(因为我假设它每次都重新初始化),而不是将其声明为页面类后面代码中的公共类。如果它在页面代码中声明为public,那么我认为在请求页面时它已初始化一次。
答案 0 :(得分:3)
这是关于变量的范围和生命周期的问题。变量的“范围”是程序文本,其中可以在没有任何限定的情况下引用变量,“生命周期”是变量有效的持续时间。
通常,最好尽可能限制变量的范围。这使得更容易推理代码。
在给出的示例代码中,有三个变量,每个变量都限定在它们出现的单个方法中。这是一件好事。假设方法的名称是准确的,您可以一目了然地看到该值发生的所有事情。
相比之下,如果通过将变量作为页面上的字段来增加变量的范围,那么该页面上的所有方法都可以访问变量。可能很难推断它的生成位置,突变方式以及用途。这使得未来应用程序的维护更加困难。
因此,我的建议是在可能的情况下继续完成您在此处所做的工作。
修改强>
回答问题的澄清:
表现不公平。您在谈论Web服务器上的纳秒。 Web应用程序受到网络或Internet上的流量的限制。任何这些选项在变量的位置上都没有明显的性能差异。
通常,性能是大型对象集合上的算法和数据结构的问题。在没有大数据结构的情况下,人类不会看到任何差异。
代码应首先设计为正确,易懂和可维护。一旦完成,那么性能只是一个问题,如果它证明是一个问题。
其他编辑
如果MyClass
是class
而不是struct
,那么代码中的三个变量只是单个引用的大小(32或64-比特,取决于平台)。它们都引用的对象仅在给定的代码示例中创建一次。
答案 1 :(得分:1)
这更多的是编码样式和访问限制,当您将其声明为页面的成员级别时,它肯定不是全局的,只是正在执行的页面对象实例的本地。
如果在整个应用程序中与类有共同的交互,您可能需要考虑其他选项,例如创建会话包装器对象,该对象将处理在会话中放置/引用类并自动进行转换,以便您可以执行某些操作DoSomethingCool(MySessionWrapper.MyClass)
等等,而不必担心跨多个类的会话引用不一致。
答案 2 :(得分:1)
我通常利用属性使其看起来更清晰:
protected MyClass Copy
{
get { return Session["MyClass"] as MyClass; }
set { Session["MyClass"] = value; }
}
现在,您可以根据需要在代码中的任何方法中使用它
我还有一个扩展方法,它允许我一直无法检查null。
public bool NotNull(HttpSessionState s, string key)
{
return s[key] != null;
}
现在你可以在会话中检查null时调用它:
Session.NotNull("MyClass")
答案 3 :(得分:1)
将实例作为参数传递给方法应该没有问题。到目前为止,您是否在应用中发现了任何性能问题?如果是这样,他们可能在您的数据库中。
将对象作为参数传递不会将整个对象复制到另一个对象中。仅传递对象的引用。内存中仍然只有一个myClass实例。
答案 4 :(得分:0)
如果MyClass的特定实例是特定于会话的,那么使用会话是可行的。是否应该参加会议的详细信息。
答案 5 :(得分:0)
一般来说,最好避免使用全局变量,因为每个人都可以访问它,这意味着高耦合。此页面说得更好:http://c2.com/cgi/wiki?GlobalVariablesAreBad
但是,我会看看myMethod [1,2]正在做什么。如果他们所做的只是访问和操纵MyClass的状态,那么他们可能属于MyClass ......
答案 6 :(得分:0)
你可以这样做。
public class MyPage
{
private MyClass myClass;
protected void Page_Load(object sender, EventArgs e)
{
if(!isPostBack)
{
myClass = (MyClass)Session["myClass"];
myMethod1();
myMethod1();
}
}
private void myMethod1()
{
// use myClass here
}
private void myMethod2()
{
// use myClass here
}
}
我看到的问题是myClass
仅在它被分配时才被分配!PostBack,所以它有点像“它现在是分配还是不分配?”如果你总是分配myClass
这个策略对我来说更有意义。