jjzjj

c# - LINQ 的问题 - 有必要添加对不需要的库的引用

coder 2024-05-25 原文

我有以下问题。我有一个包含大约 40 个项目的解决方案。 有一个项目 A 引用项目 B,项目 B 引用项目 C。项目 A 中没有任何代码使用项目 C 中的类。但是,如果我在任何代码中使用任何 LINQ 扩展方法,例如:

var r = new int[] { 1, 2, 3 }.Where(a => a > 1);

我得到编译器错误:

somefile.cs(70,13): error CS0012: The type 'XXX' is defined in an assembly that is not referenced. You must add a reference to assembly 'Project C assembly name, Version=0.0.0.0, Culture=neutral, PublicKeyToken=xxx'.

错误在使用linq扩展方法的那一行。

我正在使用 VS2010、.NET 3.5。

更新:它发生在每个扩展方法中。我在同一个文件中创建了一个类,如下所示:

public static class SomeClass
{
    public static int[] Test(this int[] a)
    {
        return a;
    }
}

然后我写了这段代码,编译因同样的错误而中断:

new int[] { 1, 2, 3 }.Test();

Update2: 好的,我找到了导致错误的原因。但我不知道为什么。以下代码导致错误:

using System.Linq;
using B;

namespace TestApp
{
    public class A
    {
        public void M()
        {
            var c = new string[] { "a", "b", "c" }.Where(s => s != null);
        }
    }
}

但是,如果我删除使用 B(我仍然遵循我的描述中的名称,即 A 引用 B,B 引用 C),它会编译。 这是项目 A 中的唯一代码。如果我删除扩展方法的使用,或者如果我删除“使用 B”,如我之前所说,它会编译。

更新3:

首先感谢大家的建议。 我能想到的最小例子如下。我创建了一个新项目,csproj 看起来像这样(什么都没有改变,只有 C 项目名称和 C 项目 guid):

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProductVersion>8.0.30703</ProductVersion>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{B649AB2C-926A-4AD1-B7E3-5A29AE1E9CC2}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>ClassLibraryTest</RootNamespace>
    <AssemblyName>ClassLibraryTest</AssemblyName>
    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="System" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\C.csproj">
      <Project>{55AFFA2D-63E0-4BA9-XXXX-B70E6A936F5E}</Project>
      <Name>C</Name>
    </ProjectReference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Class1.cs" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Properties\" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

Class1.cs 包含以下代码:

using C;

namespace TestApp
{
    public static class Ext
    {
        public static void M213dsacxvz(this string[] a)
        {
        }
    }

    public class A
    {
        public void B()
        {
            new string[] { "a", "b", "c" }.M213dsacxvz();
        }
    }
}

我得到的编译错误如下:

D:\xxx\Class1.cs(16,13): error CS0012: The type 'xxx' is defined in an assembly that is not referenced. You must add a reference to assembly 'xxx, Version=0.0.0.0, Culture=neutral, PublicKeyToken=xxx'.

如果我删除using C;,它编译得很好。

在此先感谢您的帮助。

最佳答案

这是一个重现问题的小例子。它是由 B 中的扩展方法引起的,该方法在其签名中使用 C 中定义的类型。即使未使用扩展方法,也会在搜索可通过 usings 访问的所有扩展方法的过程中触发错误。

ConsoleApplicationA.cs:

using ClassLibraryB;

namespace ConsoleApplication1
{
    public static class Extensions
    {
        public static int Test(this int a)
        {
            return a;
        }
    }

    public class ProgramA
    {
        static void Main(string[] args)
        {
            0.Test();
        }
    }
}

类库B.cs:

using ClassLibraryC;

namespace ClassLibraryB
{
    public static class Extensions
    {
        public static ClassC Test(this ClassB b)
        {
            return new ClassC();
        }
    }

    public class ClassB
    {
    }
}

类库C.cs:

namespace ClassLibraryC
{
    public class ClassC
    {
    }
}

此测试用例产生此错误:

error CS0012: The type 'ClassLibraryC.ClassC' is defined in an assembly that is not referenced. You must add a reference to assembly 'ClassLibraryC, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

编辑:

在我的意见中,这是 C# 编译器中的一个错误,因为对于您未引用的方法,它会导致您的程序无法编译,这是非常令人惊讶的行为。 C# 编译器团队可能有不同的意见。

与此同时,一个变通方法是将 B 中的扩展方法放在一个单独的 namespace 中,这些方法在其签名中使用 C 中的类型,并且仅当调用程序集同时引用 B 和 C 时才向该 namespace 添加一个 using 。或者,如果有问题的扩展方法的数量很少并且它们的值(value)有限,您可以移动或删除它们。最后,也是最明显的,您可以完成它并简单地添加对它告诉您应该添加的 C 的引用。

第二次编辑:

警告:我刚刚审查了这个以清理示例,它比我想象的要弱。仅当 A 中调用的扩展方法的名称与 B 中未调用的扩展方法的名称完全匹配时才会失败。例如,如果您将 B 中的 Test 重命名为 NotCalled它不再失败,但在最初的问题中,大概会失败。

最终编辑:

通过协作,我们缩小了重现原始问题中描述的问题的必要条件:B 中的扩展方法在其签名中使用通用类型约束的 C 类型。上面的测试用例是一个更窄的例子。具体情况显然与编译器搜索扩展方法的方式的具体实现有关。

总而言之,引用是一种运行时特性,而扩展方法是一种编译时特性。无论错误消息如何产生,如果不调用该方法,编译器需要编译时的引用,程序集不需要运行时的引用。因此错误不是编译器别无选择而是发出,这只是编译器的一种不便情况。

关于c# - LINQ 的问题 - 有必要添加对不需要的库的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5996514/

有关c# - LINQ 的问题 - 有必要添加对不需要的库的引用的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  3. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  4. ruby - 将 Bootstrap Less 添加到 Sinatra - 2

    我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它

  5. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  6. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  7. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  8. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  9. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  10. ruby - 一个 YAML 对象可以引用另一个吗? - 2

    我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的ruby​​yaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir

随机推荐