简体   繁体   English

为什么更改的页面使用的方法需要重新编译的页面?

[英]Why do I need a recompiled page when a method used by it changes?

I have an aspx page that used a method in a class in the App Code folder, doSomething(int[] x) . 我有一个aspx页面,该页面在App Code文件夹doSomething(int[] x)的类中使用了一种方法。 I changed the function definition to use an IEnumerable instead of an array: doSomething(IEnumerable<int> x) . 我将函数定义更改为使用IEnumerable而不是数组: doSomething(IEnumerable<int> x) Next, I precompiled the web site, using "allow web site to be updatable", and published the new App_Code.dll. 接下来,我使用“允许网站可更新”对网站进行了预编译,并发布了新的App_Code.dll。 Now, the precompiled version of the page gives a Server error at runtime: "Method not found". 现在,该页面的预编译版本在运行时给出服务器错误:“找不到方法”。
If I also publish the DLL generated for the page, "App_Web_[page].aspx.[random].dll", it works. 如果我还发布为页面生成的DLL“ App_Web_ [page] .aspx。[random] .dll”,则它可以工作。 So it appears the signature of the function is embedded in the compiled page somehow…? 因此,该函数的签名似乎以某种方式嵌入了已编译的页面中……? Why is this, and is there a way to avoid this problem when changing existing code? 为什么会这样,并且在更改现有代码时有办法避免此问题?
I'd hate updating all my page DLLs whenever I change code in my common classes. 每当我更改公共类中的代码时,我都不愿更新所有页面DLL。

When a page is compiled it looks at all the method signatures and essentially locks them down. 编译页面时,它会查看所有方法签名,并实质上将其锁定。 If you change the signature of a method being called, then the page will not be able to locate it until it is recompiled. 如果您更改正在调用的方法的签名,则在重新编译页面之前,该页面将无法找到它。

For example let's say you have a class like 例如,假设您有一个像

public class Dog {
  public void Walk(Int32 distance) {
    /// blah blah
  }
}

and you call this in a page code behind: 然后在后面的页面代码中调用此代码:

protected void MyButtonClick(....) {
  Dog d = new Dog();
  d.Walk(3000);
}

When this compiles down the page will expect a walk method with an Int32 signature. 当向下编译时,页面将期望带有Int32签名的walk方法。

Now, let's say we change the walk method in the Dog class to: 现在,假设我们将Dog类中的walk方法更改为:

public void Walk(Int16 distance) {
  // blah blah
}

(yes, stupid change but it highlights the issue). (是的,愚蠢的更改,但突出了问题所在)。 At this point the page will not be able to locate a Walk method that takes an Int32 parameter and so will blow up as it should. 此时,页面将无法找到采用Int32参数的Walk方法,因此将无法正常运行。


It may seem nice to just deploy the one assembly you think you need, but the fact of the matter is there could be any number of changes that occurred in the code so this is a seriously bad practice. 仅部署您认为需要的一个程序集似乎很不错,但是事实上,代码中可能发生了许多更改,因此这是一个严重的错误做法。

It is much better to make sure the entire project is consistent. 确保整个项目是一致的更好。 Even larger websites don't take that long to deploy. 甚至更大的网站也不需要花很长时间来部署。

Of course,I think that using web site projects are bad practice in and of themselves anyway. 当然,我认为使用网站项目本身都是不好的做法。 Deploying uncompiled code to the server ( really bad ), VS searching your drive to update references in the project even when you have explicitly told it which assembly to use ( usually unexpected, never good ), having all the main code in a common app_code folder ( limiting ), etc. I could go on and on here... 将未编译的代码部署到服务器( 确实很糟糕 ),即使您已明确告诉它要使用哪个程序集( 通常是意外的,永远不好 ),并且所有主代码都位于一个公共app_code文件夹中,VS仍会搜索您的驱动器以更新项目中的引用。 ( 限制 )等。我可以继续在这里...

If it's a web application then you need to recompile everytime you change server side code - does not matter if it's in a separate assembly or in a App_Code folder of your web app. 如果是Web应用程序,则每次更改服务器端代码时都需要重新编译-不管它是在单独的程序集中还是在Web应用程序的App_Code文件夹中。

Only website (not web application) allows you to change code without recompiling. 只有网站(而非Web应用程序)允许您更改代码而无需重新编译。

You need to recompile because your page was published and output to a dll in the bin folder. 您需要重新编译,因为您的页面已发布并输出到bin文件夹中的dll中。 This dll is looking for a method with a signature of: 该dll正在寻找具有以下特征的方法:

doSomething(int[])

And it isn't there any more. 而且它不再存在。 When you publish, update everything, every time. 发布时,每次都更新所有内容。


I believe the 'updatable' flag permits you to update your aspx code (ie the markup), but the codebehind files will have been compiled away. 我相信'updatable'标志允许您更新aspx代码(即标记),但是隐藏在文件后面的代码将被删除。

The following kinds of changes may cause run-time exceptions: 以下类型的更改可能会导致运行时异常:
Changing the signature of a method, or the type of a property. 更改方法的签名或属性的类型。 If the affected member is referenced by an already-compiled page, an exception will be thrown. 如果已经编译的页面引用了受影响的成员,则将引发异常。 Some signature changes would not cause compile or run-time errors if the whole site is recompiled. 如果重新编译整个站点,则某些签名更改将不会导致编译或运行时错误。 For example, the code Response.Write(ClassA.MethodA() in an .aspx page will compile and run fine whether MethodA returns an int or a short. But if the .aspx page is already compiled and you change the return type of MethodA from int to short without recompiling, a runtime exception will be thrown because the compiled code expects the int signature. 例如,无论MethodA返回int还是short,.aspx页中的代码Response.Write(ClassA.MethodA()都可以编译并正常运行。但是,如果.aspx页已经编译,并且您更改了MethodA的返回类型,从int到short而无需重新编译,则将引发运行时异常,因为编译后的代码需要int签名。

From http://msdn.microsoft.com/en-us/library/ms366723.aspx#sectionToggle5 来自http://msdn.microsoft.com/zh-cn/library/ms366723.aspx#sectionToggle5

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在静态方法中使用C#枚举类型时无需将其声明为静态? - Why do C# enum types not need to be declared static when used in a static method? 什么是Initialize方法,我真的需要一个吗? - What's the Initialize method used for and do I really need one? 我可以在派生类中隐藏虚拟方法时为什么需要声明虚拟方法 - Why do I need to declare a Virtual Method when I can Hide it in derived Class 将方法用作ThreadStart()参数时,为什么需要重载该方法? - Why I need to overload the method when use it as ThreadStart() parameter? 为什么在使用 COnfigureAwait(false) 时我有一个填充的 HttpContext? - Why do I have a filled HttpContext when COnfigureAwait(false) is used? 为什么在使用条件运算符时需要显式的ToString()? - Why do I need an explicit ToString() when using a conditional operator? 为什么在使用Linq时需要初始化out变量 - Why do I need to initialize an out variable when using Linq 使用代理时,为什么需要将KeepAlive设置为false? - Why do I need to set KeepAlive to false when using a proxy?. 当使用Rhino Mocks对函数进行存根时,为什么需要重放()? - Why do I need to Replay() when stubbing a function with Rhino Mocks? 为什么在实现INotifyPropertyChanged时需要私有字段 - Why do i need private fields when implementing INotifyPropertyChanged
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM