不同程式集,名稱空間類名和方法簽名都一樣的方法,如何呼叫

2023-02-21 09:00:35

有時候,你可能會遇到這樣的問題,不同程式集,名稱空間類名和方法簽名都一樣的方法,如何呼叫。本文將介紹如何通過別名的方式來解決這個問題。

建立兩個不同的程式集

我們來建立兩個不同的程式集,但是他們的名稱空間一樣:

dotnet new classlib -o ClassLibrary1 -n ClassLibrary1
dotnet new classlib -o ClassLibrary2 -n ClassLibrary2

修改他們的 RootNamespace 為 Example:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <RootNamespace>Example</RootNamespace>
  </PropertyGroup>

</Project>

然後,我們在兩個程式集中都建立一個類,類名也一樣,並且新增一個自定義 Where 擴充套件方法:

namespace Example
{
    public static class LinqExtensions
    {
        public static void Where(IEnumerable<int> source)
        {
            // 在這裡新增程式碼
            Console.WriteLine("ClassLibrary1.Class1.Where");
        }
    }
}

建立一個控制檯應用

然後,我們建立一個控制檯應用,來呼叫這兩個程式集中的 Where 方法:

dotnet new console -o ConsoleAppShi -n ConsoleAppShi
dotnet add ConsoleAppShi reference ClassLibrary1
dotnet add ConsoleAppShi reference ClassLibrary2

然後,我們在控制檯應用中呼叫這兩個程式集中的 Where 方法:

using Example;
var list = new int[]{1,2,3};
LinqExtensions.Where(list);

如果是這樣的話,我們會得到這個錯誤:

Ambiguous reference: Example.LinqExtensions Example.LinqExtensions match

通過別名的方式來解決

我們可以通過別名的方式來解決這個問題,首先修改專案檔案,設定兩個程式集的別名:

<Project Sdk="Microsoft.NET.Sdk">

  <ItemGroup>
    <ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj">
      <Aliases>ClassLibrary1</Aliases>
    </ProjectReference>
    <ProjectReference Include="..\ClassLibrary2\ClassLibrary2.csproj">
      <Aliases>ClassLibrary2</Aliases>
    </ProjectReference>
  </ItemGroup>
</Project>

然後,我們在控制檯應用中呼叫這兩個程式集中的 Where 方法:

extern alias ClassLibrary1;
extern alias ClassLibrary2;

var list = new[] { 1, 2, 3 };

ClassLibrary1::Example.LinqExtensions.Where(list);
ClassLibrary2::Example.LinqExtensions.Where(list);

執行就會得到這樣的結果:

ClassLibrary1.Class1.Where
ClassLibrary2.Class1.Where

為什麼會有這種問題

一般來說你會在三種情況下遇到這個問題:

  1. 某個開源專案使用 ILmerge 把多個程式集合併成一個程式集。其中一個依賴項 A 恰好也是你的依賴項,但是 A 的版本和開源專案的依賴項 A 的版本不一樣,這時候你就會遇到這個問題。
  2. 很早之前 Rx.net 正對 System.Linq.Async 進行了支援,而後來系統也內建了 System.Linq.Async。你會在使用 Rx.net 的時候遇到這個問題。
  3. 你的同事想考驗你一下,估計把自己寫的 Sqlite 擴充套件和 MSSQL 擴充套件中加入了同樣的方法簽名,然後你就會遇到這個問題。

總結

通過別名的方式,我們可以解決不同程式集,名稱空間類名和方法簽名都一樣的方法,如何呼叫的問題。

參考

感謝閱讀,如果覺得本文有用,不妨點選推薦