rksoftware

Visual Studio とか C# とかが好きです

定義済みの型 'system.object' は定義、またはインポートされていません

定義済みの型 'system.object' は定義、またはインポートされていません

Visual Studio 2019 で .NET Standard と .NET Core のプロジェクトを作ると次の様なコンパイルエラーが出ることがありました。

定義済みの型 'system.object' は定義、またはインポートされていません

リビルドや、bin と obj を削除してリビルドでは解消しませんでした。おそらく色々な状況で発生するのでしょう(というか検索してみると違うと思われる事象に対する言及がみつかる)から、これで解決する場合もあるという一例です。

■ 解消した手順

ソリューションを一度閉じてから、また開く。
これでエラーなくビルドできるようになりました。プロジェクトの「アンロード→再読み込み」ではダメでした。

秋葉原 C# もくもく会 #86 勉強会を開催しました

■ C# もくもく会

C# もくもく会 #86 を開催しました。

C# もくもく会 は東京の秋葉原で毎週木曜日に開催している .NET 系の勉強会です。
もくもく自習を基本とし、分からないことを教えあったり情報共有したりしている会です。 定期開催していますので、お時間のある時に遊びに来ていただければと思います。
ちょっと詰まった時、ネット上で聞くのははずかしいなぁ、という課題のできた時などにも思い出していただけると嬉しいです。
f:id:rksoftware:20190607212315j:plain

■ 今週の成果発表

今週は、準備の日でした

  • 入門書で C# を勉強しています
  • 技術検証しました
  • PowerShell Core をインストールしようとしました
  • ブログ書きました
  • Visual Studio のアップデートを確認しました

ちなみにこの勉強会ですが、実は公序良俗に反しなければどのような技術を扱っても大丈夫です。そもそも C# エンジニアが C# だけしか使わないというわけではありませんし。

■初心者歓迎

このもくもく会には、入門者の方も多くご参加いただいています。 突然 C# やらなければならなくなって途方に暮れている方、何となく C# をやってきたけど改めて見直してみたい方なども大歓迎です。
入門セミナー代わりでのご参加も歓迎です。プログラミング入門者の方も是非遊びに来てください。

特に C# で課題をお持ちでなくても是非遊びに来てください。

■ 目指す勉強会スタイル

世界一敷居の低い勉強会を目指しています。

何か聞きたいことがある場合は、聞く相手を決めずに独り言のようにつぶやくと誰かが拾ってくれる

何か共有したい情報を見つけた場合も、聞く相手を決めずに独り言のようにつぶやくと誰かが拾ってくれる

そんなスタイルでやっています。

■ 次回予定

次回は一週あけて 2019/06/13 に開催予定です。

C# に関心のある方、是非遊びに来てください。

Visual Studio の 16.1.2 がリリースされました

Visual Studio のアップデート 16.1.2 がリリースされました。
日本語ページが既に出ています。しかし機械翻訳感ですし、少し日本語にしていってみましょう。

■ 更新内容

問題の解決

項目タイトルはこちらより引用。太字が引用でその下の文章が私なりの解釈です。

  • UWP - 表示されていないコントロールのプロパティの XAML デザイナー
    UWP の XAML デザイナーでコントロールのプロパティが表示されないことがある(表示されることもある)

  • UWP XAML デザイナーで XAML コードを更新する方法の要素を更新しません。
    UWP の XAML デザイナーでコードやプロパティウィンドウで行った変更がプレビューに反映されないことがある(反映されるときもある)

  • XAML のプロパティとドキュメントの構造
    XAML デザイナーでプロパティウィンドウと(おそらく)ドキュメントアウトラインが空白になる

  • オブジェクトをクリックすると、プロパティが表示されないプロパティ ウィンドウ
    XAML デザイナーで一回オブジェクトをクリックするとプロパティウィンドウにプロパティが表示されるが、そこから別のオブジェクトをクリックしてもプロパティウィンドウが更新されない。(プロパティウィンドウを?)開きなおすと空白が表示される

  • すべての項目のプロパティを表示することができません。
    XAML デザイナーでプロパティウィンドウに最初にページ要素を選択したときには表示されるが、その後ページ内の(?) 要素を選択してもプロパティウィンドウが空白が表示される

  • Mac に接続する際のインストール エラー:"'X' にインストールされている Xamarin.iOS のバージョン (12.8.0.2) がお使いのバージョンより新しい"。
    Xamarin で Mac に接続する際にバージョン不整合のエラーになり接続できない。回避方法は /Library/Frameworks/Xamarin.iOS.framework を手動で消して Mac 再接続

  • 固定の右側では、titlebar VS のクラッシュのバグでソリューション名をクリックします。
    Visual Studio 自体のウィンドウのタイトルバーに表示されているソリューション名の部分を右クリックすると、Visual Studio がクラッシュすることがある(再起動することもある)

  • Azure のワークロードがインストールされた顧客のパフォーマンスを改善しました。

  • 復元および UWP のターゲット プラットフォームにサード パーティの Sdk を使用して、SDK ベースのプロジェクトのビルド中にエラーを修正しました。
    SDK ベースの UWP プロジェクトでサードパーティの SDK を使用している場合に、復元やビルド時に起こるエラーを修正しました。

  • バグを修正しましたC#コンパイラされていない正しく不完全なインターフェイスの実装、お客様に警告します。
    C# (のクラス)でインタフェースの実装が不完全の場合の警告が正しくなかったバグを修正しました。

  • Kubernetes 用の Visual Studio Tools でメッセージング エラーが向上します。
    Visual Studio Tools for Kubernetes のエラーメッセージを改善しました。

  • エラーを修正しました SymbolCheck の PR にコメントを追加するときにします。
    SymbolCheck の PR にコメントを追加するときのエラーを修正しました?

これらの問題が解消したそうです。

UWP に大きな影響があるので影響する方もとても多いと思います。素早く更新しておきましょう。

■ 更新方法

Visual Studio の更新はメニューの ツール > ツールと機能を取得 で開くインストーラーから行えます。

Xamarin で素の Activity と Forms とで画面遷移する

Xamarin.Forms は複数ページのアプリを作れますが、その実現方法は (Android の場合) 一つの Activity 上でビュー表示を切り替えるシングル Activity アプリです。つまり根っこに Activity がいるわけです。それならその Activity を他の Activity から起動したり逆に他の Activity を起動したりできるかもしれません。

ということで試してみました。

■ 素の Activity と Forms の Activity を作る

※リソースファイルなどは省略します。

素の Activity (起動 Activity) 例

まず素の Activity を作ります。今回は素のアクティビティを最初に表示される Activity としてみました。

[Activity(Label = "@string/app_name", MainLauncher = true, Theme = "@style/AppTheme.NoActionBar")]
public class MainActivity : AppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.activity_main);

        // ボタンタップで Forms のビューに遷移
        var button = FindViewById<Button>(Resource.Id.button1);
        button.Click += (sender, arg) =>
            StartActivity(new Android.Content.Intent(this, typeof(FormsActivity)));

        // 遷移時に使用する Context を雑に確保
        NativeNavigation.SetContext(this);
    }
}

基本はボタンのタップで、Forms の Activity を起動するコードがあるだけです。
あと、Forms での画面遷移を雑に実装するために、Activity を取っておく処理が最後にあります。

Forms の Activity 例

Forms の Activity は何の変哲もないただの Xamarin.Forms の Activity です。

[Activity(Label = "FormsActivity", Theme = "@style/AppTheme.NoActionBar")]
public class FormsActivity : Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

        LoadApplication(new Core.App());
    }
}

Forms のページ 例

Xamarin.Forms のページです。DependencyService で Android の画面遷移を呼ぶようにしてみました。

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FormsMainPage : ContentPage
{
    public FormsMainPage()
    {
        InitializeComponent();

        // ネイティブのビューに遷移
        button2.Clicked += (sender, arg) =>
            DependencyService.Get<INativeNavigation>().GoToNext();
    }
}

DependencyService 例

public interface INativeNavigation
{
    // ネイティブのビューに遷移
    void GoToNext();
}
using Android.Content;
using Namespace;

[assembly: Xamarin.Forms.Dependency(typeof(NativeNavigation))]
namespace Namespace
{
    class NativeNavigation : Core.INativeNavigation
    {
        static Context _context;
        public static void SetContext(Context context) => _context = context;
        static Context Context => _context;

        public void GoToNext() =>
            Context.StartActivity(new Intent(Context, typeof(MainActivity)));
    }
}

■ 実行

ボタンのタップで 素の Activity → Forms の Activity → 素の Activity ... と遷移できました。

こんなことをして良いものなのか、この経験が生きる日がいずれ来るのか分かりませんが、もしかしたら Xamarin に限らず何かでこの経験に救われる日が来るかもしれません。
来ない気がしますけれど。

C# で令和元年を表示する

先日、de:code 2019 に参加してきました。

その中で最後に聴講した「C# ドキドキ・ライブコーディング対決 @ de:code - ONLY C#!! Blazor Web 開発バトル -」というセッションがとても面白く、選択して大正解でした。

登壇者の皆様、素晴らしいセッションをありがとうございます。

■ 私も書いてみたい!

その中で出たお題として C# で令和を表示というものがあって、自分だったらどう書けるだろう? と思ったのでちょっと電車の中で書いてみました。Blazor はまだ着手していないので、コンソールアプリです。Console.ReadLine で読んだ西暦日付テキストを和暦にして Console.WriteLine しています。
電車の中なのであまりちゃんとは考えもデバッグもしてません。バグありそう。

■ 私なりの令和元年

using System;
using System.Linq;

namespace SeirekiToWareki
{
    class Program
    {
        static void Main(string[] args)
        {
            // 入力を読み取り
            var input = Console.ReadLine();

            // 和暦に変換
            var wareki = new (DateTime start, string gengo)[] { (new DateTime(2019, 05, 01), "令和"), (new DateTime(1989, 01, 08), "平成"), (new DateTime(1926, 12, 25), "昭和"), (new DateTime(1912, 07, 30), "大正"), (new DateTime(1868, 10, 23), "明治"), }.OrderBy(g => g.start).Select(g => new { Seireki = DateTime.TryParse(input, out var seireki) ? (DateTime?)seireki : null, Gengo = g }).Where(g => g.Seireki != null).TakeWhile(g => g.Seireki >= g.Gengo.start).Select(g => new { year = g.Seireki.Value.Year - g.Gengo.start.Year + 1, Seireki = g.Seireki.Value, Gengo = g.Gengo.gengo }).Select(g => $"{g.Gengo}{(g.year == 1 ? "" : g.year.ToString())}年{g.Seireki.Month}月{g.Seireki.Day}日").LastOrDefault() ?? "和暦に変換できませんでした.";

            // 和暦を表示
            Console.WriteLine(wareki);
        }
    }
}

■ 実行してみる

2019/05/01
令和元年5月1日

なんだかそれらしい結果になりました。

ASP.NET Core MVC にコントローラーを追加する

以前に ASP.NET MVC にコントローラーを追加する記事を書きました。

簡単に言うと、ASP.NET MVC のカレントのディレクトリに Controller クラスの含まれる DLL を置いてしまうと作りによってはそれだけで、実行されている ASP.NET MVC プロジェクト自身に手を加えることなく Controller を追加できてしまうというものでした。
手をあまりかけずに作った ASP.NET MVC アプリに発生する抜け穴の様なもので、本来はアプリでちゃんと設定をしてできないようにしておくのが良いものなのだろうとは思います。

■ ASP.NET Core MVC

ASP.NET Core MVC では基本状態で上で書いたような追加はできなくなっているようです。同じようなことを実現するには Startup.cs に手を入れて穴をあけておく必要があるようです。

テンプレートで生まれた状態

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

この ConfigureServices メソッドに手を加えます。
今回は、カレントのディレクトリではなく、拡張機能の体で Extensions というフォルダの中に DLL を置くという想定で書いてみました。

書き加えた状態

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        var builder = services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        var entryAssembly = System.Reflection.Assembly.GetEntryAssembly().Location;
        var entryDirectory = System.IO.Path.GetDirectoryName(entryAssembly);

        var extensionDirectory = System.IO.Path.Combine(entryDirectory, "Extensions");
        if (System.IO.Directory.Exists(extensionDirectory))
        {
            var extensionDlls = System.IO.Directory.GetFiles(extensionDirectory, "*.dll");
            var extensionAssemblys = extensionDlls.Select(dll => System.Reflection.Assembly.LoadFile(dll)).ToArray();

            foreach (var assembly in extensionAssemblys)
                builder.AddApplicationPart(assembly);
        }
    }

追加する Controller を含んだ DLL

.NET Core のクラスライブラリプロジェクトを作成します。

using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;

namespace ExtensionDll
{
    [Route("api/[controller]")]
    [ApiController]
    public class ExtensionController : ControllerBase
    {
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new string[] { "saitama", "gunma" };
        }
    }
}

このクラスを含んだ DLL を Extensions ディレクトリに置いて ASP.NET Core MVC プロジェクトを実行。ブラウザで localhost:5000/api/Extensionlocalhost:5001/api/Extension にアクセスすると

f:id:rksoftware:20190529033657j:plain

とブラウザに表示され、Controller の追加が確認できました。

Visual Studio の 16.1.1 がリリースされました

Visual Studio のアップデート 16.1.1 がリリースされました。
日本語が出ていないので英語サイトを見て行きましょう。

■ 更新内容

問題の解決

  • (C++ で?)tasks.vs.json で Open Folder にデフォルトの contextType のカスタムタスクの追加が機能しない問題(すみません。私の英語力と C++ 開発環境力が足りなくて、ちょっと私には何を言っているかわからない感じがありました...)
  • C++ で診断ツールのヒープのスナップショットをとる機能が管理者でないと動作しない問題
  • (C++ で?)メソッド上にカーソルを乗せた時に表示される Quick Info の search online リンクをクリックすると VS がクラッシュやフリーズする問題
  • LiveShare のゲストセッション中に特定の機能(例えば Find All References) が動作しないことがある問題
  • Visual Studio 終了後に最大30秒、devenv.exe がハングすることがある問題

が解消したそうです。

影響のない方も多いかもしれませんが、取り合えず更新しておきましょう。

■ 更新方法

Visual Studio の更新はメニューの ツール > ツールと機能を取得 で開くインストーラーから行えます。