C#でvar型を使うとコンパイルできない件

C# コンピュータ
C#

var型は多分Variantの略だと思いますが、ありとあらゆる型を受け付ける型で、そもそも型を事前に宣言する意味からすると、「事前には型は未定です」と型の宣言の意味があるような無いような気がする型です。
コンパイル型の言語の場合、コンパイル時にエラーチェックしてくれるので、しっかり型を指定したほうが良いのは理解しているのですが、利便性を優先してあまり型の意識する必要が無い場面ではvar型を使いたくなります。

varを使ったサンプルプログラムを作ってみます。

プロジェクト:VerCheck.csproj

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>  
   <AssemblyName>VerCheck</AssemblyName>  
    <OutputPath>Bin\</OutputPath>  
  </PropertyGroup>  
  <ItemGroup>
    <Compile Include="*.cs"/>
  </ItemGroup>
  <Target Name="Build" Inputs="@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe">
	<MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
    <Csc Sources="@(Compile)" TargetType="exe" OutputAssembly="$(OutputPath)$(AssemblyName).exe"/>
  </Target>
  <Target Name="Clean" >  
    <Delete Files="$(OutputPath)$(AssemblyName).exe" />
  </Target>
  <Target Name="Rebuild" DependsOnTargets="Clean;Build" />
  <Target Name="Run" DependsOnTargets="Rebuild">
  	<Exec Command="$(OutputPath)$(AssemblyName).exe" />
  </Target>
</Project>

ソース:VerCheck.cs

using System;
namespace VerCheck
{
    class Program
    {
        static void Main(string[] args)
        {
        	var s = "Hello World!!"
            Console.WriteLine(s);
        }
    }
}

“Hello World!!”文字列をvar型の変数sに代入しコンソールに出力するプログラムになります。
それではコンパイルして実行してみます。

PS H:\csharp\VerCheck> msbuild
Microsoft (R) Build Engine バージョン 4.8.3761.0
[Microsoft .NET Framework、バージョン 4.0.30319.42000]
Copyright (C) Microsoft Corporation. All rights reserved.

2020/01/07 10:54:56 にビルドを開始しました。
ノード 1 上のプロジェクト "H:\csharp\VerCheck\VerCheck.csproj" (既定のターゲット
)。
Build:
  C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Csc.exe /out:Bin\VerCheck.exe
   /target:exe VerCheck.cs
VerCheck.cs(8,10): error CS0246: 型または名前空間名 'var' が見つかりませんでした
。using ディレクティブまたはアセンブリ参照が不足しています。 [H:\csharp\VerCheck\VerCheck.csproj]
VerCheck.cs(9,13): error CS1502: 'System.Console.WriteLine(bool)' に最も適してい
るオーバーロード メソッドには無効な引数がいくつか含まれています。 [H:\csharp\VerCheck\VerChe
ck.csproj]
VerCheck.cs(9,31): error CS1503: 引数 '1': 'var' から 'bool' に変換できません。
[H:\csharp\VerCheck\VerCheck.csproj]
プロジェクト "H:\csharp\VerCheck\VerCheck.csproj" (既定のターゲット) のビルドが
終了しました -- 失敗。


ビルドに失敗しました。

"H:\csharp\VerCheck\VerCheck.csproj" (既定のターゲット) (1) ->
(Build ターゲット) ->
  VerCheck.cs(8,10): error CS0246: 型または名前空間名 'var' が見つかりませんでし
た。using ディレクティブまたは
アセンブリ参照が不足しています。 [H:\csharp\VerCheck\VerCheck.csproj]
  VerCheck.cs(9,13): error CS1502: 'System.Console.WriteLine(bool)' に最も適して
いるオーバ
ーロード メソッドには無効な引数がいくつか含まれています。 [H:\csharp\VerCheck\Ve
rCheck.csproj]
  VerCheck.cs(9,31): error CS1503: 引数 '1': 'var' から 'bool' に変換できません
。 [H:\csharp\VerCheck\VerCheck.csproj]

    0 個の警告
    3 エラー

経過時間 00:00:00.22

あれ、コンパイルが失敗しています。コンパイラがvar型なぞ知らないと言っているように見受けられます。
C#でvar型が導入されたのはWikiで調べると3.0からとの事ですが、実行環境のバージョンは知りませんがWindowsの標準的環境(今時Windows7で標準的というのはあれですが…)で、それほど古いバージョンがインストールされているとは考えにくい。

コンパイルログを少し見ていると、csc.exeのパスがFramework64のv2.0のが指定されています。.Net Frameworkのバージョンは確かv4.0を指すようにパスを切っているはずなのに古いバージョンが指定されています。
どうやらこの辺りにvar型が通らない原因がありそうです。

csc.exeが4.0を使うように.csprojのProjectを次のように変更してみます。

<Project ToolsVersion="4.0" xmlns="http~略~>

再度MSBuildしてみるとビルドが成功しました。cscのパスもv4.0が指定されていました。

この辺りはVisuial Studioを使えば悩む必要が無いのかもしれませんが、バージョンアップが体感出来るのもまぁ良いかと思います。
これでつまずくと言うことは参照するdll関連のバージョンでもハマりそうな予感がします。

修正後のVerCheck.csproj

<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>  
   <AssemblyName>VerCheck</AssemblyName>  
    <OutputPath>Bin\</OutputPath>  
  </PropertyGroup>  
  <ItemGroup>
    <Compile Include="*.cs"/>
  </ItemGroup>
  <Target Name="Build" Inputs=&quot;@(Compile)" Outputs="$(OutputPath)$(AssemblyName).exe">
	<MakeDir Directories="$(OutputPath)" Condition="!Exists('$(OutputPath)')" />
    <Csc Sources="@(Compile)" TargetType="exe" OutputAssembly="$(OutputPath)$(AssemblyName).exe"/>
  </Target>
  <Target Name="Clean" >  
    <Delete Files="$(OutputPath)$(AssemblyName).exe" />
  </Target>
  <Target Name="Rebuild" DependsOnTargets="Clean;Build" />
  <Target Name="Run" DependsOnTargets="Rebuild">
  	<Exec Command="$(OutputPath)$(AssemblyName).exe" />
  </Target>
</Project>

 

コメント