現在、C→C#の移植作業をしています。
手作業でちまちましている箇所を、自動化できたらいいなと思いました。
そこで、構造体をクラスに移植する場合を考えます。
使用するもの
方法
① テキストテンプレートを作成する。拡張子は.tt。
【説明】
<#@ ディレクティブの指定 #>
<# 複数のステートメント #>
<#= 単一の式 #>
<#+ 関数やクラス #>
<#>がない箇所はそのまま作成される。
<#@ template debug="false" hostspecific="true" language="C#" #> ←ポイント①ファイルを読み込むときはhostspecific="true"にする
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Test
{
<#
string cName = string.Empty;
foreach (var line in System.IO.File.ReadLines(this.Host.ResolvePath("Data.txt"), Encoding.GetEncoding("shift_jis")))
{
var s = line.Split('\t').ToList();
if(cName == string.Empty)
{
cName = s.First();
#>
public class <#= cName #>
{
<# continue;
}
var data = new Data(s);
#>
/// <summary>
/// <#= data.Description #>
/// </summary>
public <#= data.Type #> <#= data.ItemName #> { get; set; }
<#
}
#>
}
}
<#+
private class Data
{
// クラス名
public string ClassName { get; set; }
// 型
public string Type { get; set; }
// 項目名
public string ItemName { get; set; }
// 説明
public string Description { get; set; }
private static Dictionary<string, string> TypDic = new Dictionary<string, string>()
{
{"UD", "int"}, ←ポイント②定義しておいたら後で迷わなくてすむ
{"DD", "uint"},
{"UW", "short"},
{"UB", "byte"},
};
public Data(List<string> s)
{
Type = TypParse(s[0]);
ItemName = ItemParse(s[1]);
Description = s[2];
}
private string TypParse(string str)
{
string ret;
if(!TypDic.TryGetValue(str, out ret))
{
return "string";
}
return ret;
}
private string ItemParse(string str)
{
return str.Substring(0, 1).ToUpper() + str.Substring(1).ToLower();
}
}
#>
② 新規ファイルを作成。一行目に作成したいクラス名、以降の行は型,項目名,説明をタブ区切りで定義する。
(そもそもこれを作るのが面倒ということは置いておく...)
(例)
学生クラス UD id 学籍番号 char name 氏名 UD age 年齢 UD schoolyear 学年
③ テンプレートを実行する。
実行結果は下記のようになる。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Test { public class 学生クラス { ////// 学籍番号 /// public int Id { get; set; } ////// 氏名 /// public string Name { get; set; } ////// 年齢 /// public int Age { get; set; } ////// 学年 /// public int Schoolyear { get; set; } } }
まとめ
【メリット】
移植元ソースは独自の型が定義されているので、自分で確認して移植しないといけない。
ディクショナリーであらかじめ定義しておけば、悩まなくてすむし、忘れていても問題ない。
また、データが大量にある場合は、手作業で行うよりはミスが減るはず。
【デメリット】
移植元ソースをただ読み込むだけだと使用できないので、コピペしてファイルを作成しないといけない。
(読み込みを工夫したらいけますかね?)
結局そのひと手間が必要なので、自動化の道は遠い...。
現状関係ないが、エクセルを読み込むこともできるらしいので、エクセルの大量データを定義する場合は多少は使えるかもしれない。