rksoftware

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

.NET Standard で使える DataTable (その3 / Extensions)

DataTable が、.NET Standard で使えるようになっていることに気が付いたので少し調べてみています。

前回までのあらすじ(DataTable の API の比較)

前回までのあらすじ(DataRow の API の比較)

ひとまずこれまでの確認で、DataTable、DataRow ともに全ての コンストラクタ/メソッド/プロパティ が .NET Framework と同様に使えることが確認できました。
他にも DataColumn などのクラスもありますが、こちらはまあ良いでしょう。DataTable を愛する方々があまり使い込んでいるクラスではないと思いますし。

■ .NET Standard で使えない DataTable

しかし、安心するのはまだ早いです。
DataTable/DataRow のメソッドはこれだけではありません。C# には拡張メソッドという機能があります。 https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/extension-methods

油断せずこちらも確認してみましょう。

.NET Framework .NET Stabdard .NET Core
DataTableExtensions ある ない ない
DataRowExtensions ある ない ない

拡張メソッドはないようです。 では、拡張メソッドがないとどのメソッドが使えないのでしょうか?

DataTableExtensions のメソッド

  • AsDataView
  • AsEnumerable
  • CopyToDataTable

DataRowExtensions のメソッド

  • T Field

何気に結構使われているだろうメソッドがないことがわかりました。
油断なりませんね。

.NET Standard で使える DataTable (その2 / DataRow)

DataTable が、.NET Standard で使えるようになっていることに気が付いたので少し調べてみています。

前回(DataTable の API の比較)

■ DataRow

前回は DataTable を見てみましたが、その Table の一つ一つの行のデータを表す DataRow クラスも切っても切れない強いつながりのあるクラスです。今回はこの DataRow クラスを見てみましょう。

基底クラス インタフェース

.NET Framework .NET Stabdard .NET Core
なし なし なし

一致:1 / 差:0

コンストラクタ

.NET Framework .NET Stabdard .NET Core
protected internal DataRow(DataRowBuilder builder); protected internal DataRow(DataRowBuilder builder); protected internal DataRow(DataRowBuilder builder);

一致:1 / 差:0

インデクサー

.NET Framework .NET Stabdard .NET Core
public object this[DataColumn column] { get; set; } public object this[DataColumn column] { get; set; } public object this[DataColumn column] { get; set; }
public object this[string columnName] { get; set; } public object this[string columnName] { get; set; } public object this[string columnName] { get; set; }
public object this[int columnIndex] { get; set; } public object this[int columnIndex] { get; set; } public object this[int columnIndex] { get; set; }
public object this[DataColumn column, DataRowVersion version] { get; } public object this[DataColumn column, DataRowVersion version] { get; } public object this[DataColumn column, DataRowVersion version] { get; }
public object this[string columnName, DataRowVersion version] { get; } public object this[string columnName, DataRowVersion version] { get; } public object this[string columnName, DataRowVersion version] { get; }
public object this[int columnIndex, DataRowVersion version] { get; } public object this[int columnIndex, DataRowVersion version] { get; } public object this[int columnIndex, DataRowVersion version] { get; }

一致:6 / 差:0

プロパティ

.NET Framework .NET Stabdard .NET Core
public DataTable Table { get; } public DataTable Table { get; } public DataTable Table { get; }
public DataRowState RowState { get; } public DataRowState RowState { get; } public DataRowState RowState { get; }
public string RowError { get; set; } public string RowError { get; set; } public string RowError { get; set; }
public object ItemArray { get; set; } public object ItemArray { get; set; } public object ItemArray { get; set; }
public bool HasErrors { get; } public bool HasErrors { get; } public bool HasErrors { get; }

一致:5 / 差:0

メソッド

.NET Framework .NET Stabdard .NET Core
public void AcceptChanges(); public void AcceptChanges(); public void AcceptChanges();
public void BeginEdit(); public void BeginEdit(); public void BeginEdit();
public void CancelEdit(); public void CancelEdit(); public void CancelEdit();
public void ClearErrors(); public void ClearErrors(); public void ClearErrors();
public void Delete(); public void Delete(); public void Delete();
public void EndEdit(); public void EndEdit(); public void EndEdit();
public DataRow GetChildRows(string relationName); public DataRow GetChildRows(string relationName); public DataRow GetChildRows(string relationName);
public DataRow GetChildRows(string relationName, DataRowVersion version); public DataRow GetChildRows(string relationName, DataRowVersion version); public DataRow GetChildRows(string relationName, DataRowVersion version);
public DataRow GetChildRows(DataRelation relation); public DataRow GetChildRows(DataRelation relation); public DataRow GetChildRows(DataRelation relation);
public DataRow GetChildRows(DataRelation relation, DataRowVersion version); public DataRow GetChildRows(DataRelation relation, DataRowVersion version); public DataRow GetChildRows(DataRelation relation, DataRowVersion version);
public string GetColumnError(string columnName); public string GetColumnError(string columnName); public string GetColumnError(string columnName);
public string GetColumnError(DataColumn column); public string GetColumnError(DataColumn column); public string GetColumnError(DataColumn column);
public string GetColumnError(int columnIndex); public string GetColumnError(int columnIndex); public string GetColumnError(int columnIndex);
public DataColumn GetColumnsInError(); public DataColumn GetColumnsInError(); public DataColumn GetColumnsInError();
public DataRow GetParentRow(string relationName, DataRowVersion version); public DataRow GetParentRow(string relationName, DataRowVersion version); public DataRow GetParentRow(string relationName, DataRowVersion version);
public DataRow GetParentRow(string relationName); public DataRow GetParentRow(string relationName); public DataRow GetParentRow(string relationName);
public DataRow GetParentRow(DataRelation relation, DataRowVersion version); public DataRow GetParentRow(DataRelation relation, DataRowVersion version); public DataRow GetParentRow(DataRelation relation, DataRowVersion version);
public DataRow GetParentRow(DataRelation relation); public DataRow GetParentRow(DataRelation relation); public DataRow GetParentRow(DataRelation relation);
public DataRow GetParentRows(string relationName, DataRowVersion version); public DataRow GetParentRows(string relationName, DataRowVersion version); public DataRow GetParentRows(string relationName, DataRowVersion version);
public DataRow GetParentRows(string relationName); public DataRow GetParentRows(string relationName); public DataRow GetParentRows(string relationName);
public DataRow GetParentRows(DataRelation relation); public DataRow GetParentRows(DataRelation relation); public DataRow GetParentRows(DataRelation relation);
public DataRow GetParentRows(DataRelation relation, DataRowVersion version); public DataRow GetParentRows(DataRelation relation, DataRowVersion version); public DataRow GetParentRows(DataRelation relation, DataRowVersion version);
public bool HasVersion(DataRowVersion version); public bool HasVersion(DataRowVersion version); public bool HasVersion(DataRowVersion version);
public bool IsNull(DataColumn column); public bool IsNull(DataColumn column); public bool IsNull(DataColumn column);
public bool IsNull(int columnIndex); public bool IsNull(int columnIndex); public bool IsNull(int columnIndex);
public bool IsNull(string columnName); public bool IsNull(string columnName); public bool IsNull(string columnName);
public bool IsNull(DataColumn column, DataRowVersion version); public bool IsNull(DataColumn column, DataRowVersion version); public bool IsNull(DataColumn column, DataRowVersion version);
public void RejectChanges(); public void RejectChanges(); public void RejectChanges();
public void SetAdded(); public void SetAdded(); public void SetAdded();
public void SetColumnError(int columnIndex, string error); public void SetColumnError(int columnIndex, string error); public void SetColumnError(int columnIndex, string error);
public void SetColumnError(DataColumn column, string error); public void SetColumnError(DataColumn column, string error); public void SetColumnError(DataColumn column, string error);
public void SetColumnError(string columnName, string error); public void SetColumnError(string columnName, string error); public void SetColumnError(string columnName, string error);
public void SetModified(); public void SetModified(); public void SetModified();
public void SetParentRow(DataRow parentRow, DataRelation relation); public void SetParentRow(DataRow parentRow, DataRelation relation); public void SetParentRow(DataRow parentRow, DataRelation relation);
public void SetParentRow(DataRow parentRow); public void SetParentRow(DataRow parentRow); public void SetParentRow(DataRow parentRow);
protected void SetNull(DataColumn column); protected void SetNull(DataColumn column); protected void SetNull(DataColumn column);

一致:36 / 差:0

■ 合計

完全に一致!

一致:49 / 差:0
という結果になりました。

古くからの .NET Framework ユーザーには DataTable/DataRow を愛している方も多いですが、これなら安心ですね!

ただし、今回までで DataTable と DataRow クラスだけを比較しています。実は、DataTable に関する機能はそれだけでは語り切れないのでそのあたりは、今後また確認して行こうと思います。

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

■ C# もくもく会

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

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

f:id:rksoftware:20180706011858j:plain

今週から成果発表タイムを復活してみましたが、まだ告知ページにちょっと掲載しただけですから、当然皆さんの準備もできていない状態でまだこれからというところでした。
しばらくは継続して行こうと思っています。

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

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

■ 目指す勉強会スタイル

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

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

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

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

■ 次回予定

次回は 2018/07/12 に開催予定です。

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

.NET Standard で使える DataTable

皆さんは .NET Framework で使えた DataTable というクラスをご存知でしょうか?
現在はほとんど使われなくなっているので、現代のコードでは見る機会がなく知らない方が多いのではないかと思います。

しかし、実は古くからの .NET Framework ユーザーには根強い人気がありいまだに愛用している現場も多くあるらしいです。

そんな DataTable ですが、.NET Standard で使えるようになっていることに気が付いたので少し調べてみることにしました。

■ API の違い

.NET Framework と .NET Core など実装ごとに実はいくらか API が異なっています。
しかし、それではいろいろ困るので、統一した規格として .NET Standard というものがあります。どの実装でも最低限持たなければならない API です。
ということは、.NET Standard ⊂ .NET Framework の関係。.NET Framework の機能すべてが .NET Standard で使えるとは限りません。

■ 比較してみた

というわけで、各実装で DataTable の API にどのような違いがあるのか、比較してみました。

基底クラス

.NET Framework .NET Stabdard .NET Core
MarshalByValueComponent MarshalByValueComponent MarshalByValueComponent

一致:1 / 差:0

インタフェース

.NET Framework .NET Stabdard .NET Core
IListSource IListSource IListSource
ISupportInitializeNotification ISupportInitializeNotification ISupportInitializeNotification
ISupportInitialize ISupportInitialize ISupportInitialize
Iserializable Iserializable Iserializable
IXmlSerializable IXmlSerializable IXmlSerializable

一致:5 / 差:0

フィールド

.NET Framework .NET Stabdard .NET Core
protected internal bool fInitInProgress; protected internal bool fInitInProgress; protected internal bool fInitInProgress;

一致:1 / 差:0

コンストラクタ

.NET Framework .NET Stabdard .NET Core
public DataTable(); public DataTable(); public DataTable();
public DataTable(string tableName); public DataTable(string tableName); public DataTable(string tableName);
public DataTable(string tableName, string tableNamespace); public DataTable(string tableName, string tableNamespace); public DataTable(string tableName, string tableNamespace);
protected DataTable(SerializationInfo info, StreamingContext context); protected DataTable(SerializationInfo info, StreamingContext context); protected DataTable(SerializationInfo info, StreamingContext context);

一致:4 / 差:0

プロパティ

.NET Framework .NET Stabdard .NET Core
public CultureInfo Locale { get; set; } public CultureInfo Locale { get; set; } public CultureInfo Locale { get; set; }
public bool HasErrors { get; } public bool HasErrors { get; } public bool HasErrors { get; }
public PropertyCollection ExtendedProperties { get; } public PropertyCollection ExtendedProperties { get; } public PropertyCollection ExtendedProperties { get; }
public string DisplayExpression { get; set; } public string DisplayExpression { get; set; } public string DisplayExpression { get; set; }
public DataView DefaultView { get; } public DataView DefaultView { get; } public DataView DefaultView { get; }
public DataColumnCollection Columns { get; } public DataColumnCollection Columns { get; } public DataColumnCollection Columns { get; }
public ConstraintCollection Constraints { get; } public ConstraintCollection Constraints { get; } public ConstraintCollection Constraints { get; }
public int MinimumCapacity { get; set; } public int MinimumCapacity { get; set; } public int MinimumCapacity { get; set; }
public DataRelationCollection ChildRelations { get; } public DataRelationCollection ChildRelations { get; } public DataRelationCollection ChildRelations { get; }
public SerializationFormat RemotingFormat { get; set; } public SerializationFormat RemotingFormat { get; set; } public SerializationFormat RemotingFormat { get; set; }
public bool IsInitialized { get; } public bool IsInitialized { get; } public bool IsInitialized { get; }
public DataSet DataSet { get; } public DataSet DataSet { get; } public DataSet DataSet { get; }
public DataRelationCollection ParentRelations { get; } public DataRelationCollection ParentRelations { get; } public DataRelationCollection ParentRelations { get; }
public string TableName { get; set; } public string TableName { get; set; } public string TableName { get; set; }
public DataRowCollection Rows { get; } public DataRowCollection Rows { get; } public DataRowCollection Rows { get; }
public bool CaseSensitive { get; set; } public bool CaseSensitive { get; set; } public bool CaseSensitive { get; set; }
public string Namespace { get; set; } public string Namespace { get; set; } public string Namespace { get; set; }
public string Prefix { get; set; } public string Prefix { get; set; } public string Prefix { get; set; }
public override ISite Site { get; set; } public override ISite Site { get; set; } public override ISite Site { get; set; }
public DataColumn PrimaryKey { get; set; } public DataColumn PrimaryKey { get; set; } public DataColumn PrimaryKey { get; set; }

一致:20 / 差:0

イベント

.NET Framework .NET Stabdard .NET Core
public event DataColumnChangeEventHandler ColumnChanging; public event DataColumnChangeEventHandler ColumnChanging; public event DataColumnChangeEventHandler ColumnChanging;
public event DataColumnChangeEventHandler ColumnChanged; public event DataColumnChangeEventHandler ColumnChanged; public event DataColumnChangeEventHandler ColumnChanged;
public event EventHandler Initialized; public event EventHandler Initialized; public event EventHandler Initialized;
public event DataRowChangeEventHandler RowChanged; public event DataRowChangeEventHandler RowChanged; public event DataRowChangeEventHandler RowChanged;
public event DataRowChangeEventHandler RowChanging; public event DataRowChangeEventHandler RowChanging; public event DataRowChangeEventHandler RowChanging;
public event DataRowChangeEventHandler RowDeleting; public event DataRowChangeEventHandler RowDeleting; public event DataRowChangeEventHandler RowDeleting;
public event DataRowChangeEventHandler RowDeleted; public event DataRowChangeEventHandler RowDeleted; public event DataRowChangeEventHandler RowDeleted;
public event DataTableClearEventHandler TableClearing; public event DataTableClearEventHandler TableClearing; public event DataTableClearEventHandler TableClearing;
public event DataTableClearEventHandler TableCleared; public event DataTableClearEventHandler TableCleared; public event DataTableClearEventHandler TableCleared;
public event DataTableNewRowEventHandler TableNewRow; public event DataTableNewRowEventHandler TableNewRow; public event DataTableNewRowEventHandler TableNewRow;
public static XmlSchemaComplexType GetDataTableSchema(XmlSchemaSet schemaSet); public static XmlSchemaComplexType GetDataTableSchema(XmlSchemaSet schemaSet); public static XmlSchemaComplexType GetDataTableSchema(XmlSchemaSet schemaSet);

一致:11 / 差:0

メソッド

.NET Framework .NET Stabdard .NET Core
public void AcceptChanges(); public void AcceptChanges(); public void AcceptChanges();
public virtual void BeginInit(); public virtual void BeginInit(); public virtual void BeginInit();
public void BeginLoadData(); public void BeginLoadData(); public void BeginLoadData();
public void Clear(); public void Clear(); public void Clear();
public virtual DataTable Clone(); public virtual DataTable Clone(); public virtual DataTable Clone();
public object Compute(string expression, string filter); public object Compute(string expression, string filter); public object Compute(string expression, string filter);
public DataTable Copy(); public DataTable Copy(); public DataTable Copy();
public DataTableReader CreateDataReader(); public DataTableReader CreateDataReader(); public DataTableReader CreateDataReader();
public virtual void EndInit(); public virtual void EndInit(); public virtual void EndInit();
public void EndLoadData(); public void EndLoadData(); public void EndLoadData();
public DataTable GetChanges(DataRowState rowStates); public DataTable GetChanges(DataRowState rowStates); public DataTable GetChanges(DataRowState rowStates);
public DataTable GetChanges(); public DataTable GetChanges(); public DataTable GetChanges();
public DataRow GetErrors(); public DataRow GetErrors(); public DataRow GetErrors();
public virtual void GetObjectData(SerializationInfo info, StreamingContext context); public virtual void GetObjectData(SerializationInfo info, StreamingContext context); public virtual void GetObjectData(SerializationInfo info, StreamingContext context);
public void ImportRow(DataRow row); public void ImportRow(DataRow row); public void ImportRow(DataRow row);
public void Load(IDataReader reader, LoadOption loadOption); public void Load(IDataReader reader, LoadOption loadOption); public void Load(IDataReader reader, LoadOption loadOption);
public void Load(IDataReader reader); public void Load(IDataReader reader); public void Load(IDataReader reader);
public virtual void Load(IDataReader reader, LoadOption loadOption, FillErrorEventHandler errorHandler); public virtual void Load(IDataReader reader, LoadOption loadOption, FillErrorEventHandler errorHandler); public virtual void Load(IDataReader reader, LoadOption loadOption, FillErrorEventHandler errorHandler);
public DataRow LoadDataRow(object values, LoadOption loadOption); public DataRow LoadDataRow(object values, LoadOption loadOption); public DataRow LoadDataRow(object values, LoadOption loadOption);
public DataRow LoadDataRow(object values, bool fAcceptChanges); public DataRow LoadDataRow(object values, bool fAcceptChanges); public DataRow LoadDataRow(object values, bool fAcceptChanges);
public void Merge(DataTable table, bool preserveChanges, MissingSchemaAction missingSchemaAction); public void Merge(DataTable table, bool preserveChanges, MissingSchemaAction missingSchemaAction); public void Merge(DataTable table, bool preserveChanges, MissingSchemaAction missingSchemaAction);
public void Merge(DataTable table, bool preserveChanges); public void Merge(DataTable table, bool preserveChanges); public void Merge(DataTable table, bool preserveChanges);
public void Merge(DataTable table); public void Merge(DataTable table); public void Merge(DataTable table);
public DataRow NewRow(); public DataRow NewRow(); public DataRow NewRow();
public XmlReadMode ReadXml(XmlReader reader); public XmlReadMode ReadXml(XmlReader reader); public XmlReadMode ReadXml(XmlReader reader);
public XmlReadMode ReadXml(string fileName); public XmlReadMode ReadXml(string fileName); public XmlReadMode ReadXml(string fileName);
public XmlReadMode ReadXml(Stream stream); public XmlReadMode ReadXml(Stream stream); public XmlReadMode ReadXml(Stream stream);
public XmlReadMode ReadXml(TextReader reader); public XmlReadMode ReadXml(TextReader reader); public XmlReadMode ReadXml(TextReader reader);
public void ReadXmlSchema(string fileName); public void ReadXmlSchema(string fileName); public void ReadXmlSchema(string fileName);
public void ReadXmlSchema(TextReader reader); public void ReadXmlSchema(TextReader reader); public void ReadXmlSchema(TextReader reader);
public void ReadXmlSchema(Stream stream); public void ReadXmlSchema(Stream stream); public void ReadXmlSchema(Stream stream);
public void ReadXmlSchema(XmlReader reader); public void ReadXmlSchema(XmlReader reader); public void ReadXmlSchema(XmlReader reader);
public void RejectChanges(); public void RejectChanges(); public void RejectChanges();
public virtual void Reset(); public virtual void Reset(); public virtual void Reset();
public DataRow Select(); public DataRow Select(); public DataRow Select();
public DataRow Select(string filterExpression); public DataRow Select(string filterExpression); public DataRow Select(string filterExpression);
public DataRow Select(string filterExpression, string sort); public DataRow Select(string filterExpression, string sort); public DataRow Select(string filterExpression, string sort);
public DataRow Select(string filterExpression, string sort, DataViewRowState recordStates); public DataRow Select(string filterExpression, string sort, DataViewRowState recordStates); public DataRow Select(string filterExpression, string sort, DataViewRowState recordStates);
public override string ToString(); public override string ToString(); public override string ToString();
public void WriteXml(string fileName); public void WriteXml(string fileName); public void WriteXml(string fileName);
public void WriteXml(Stream stream, XmlWriteMode mode); public void WriteXml(Stream stream, XmlWriteMode mode); public void WriteXml(Stream stream, XmlWriteMode mode);
public void WriteXml(string fileName, bool writeHierarchy); public void WriteXml(string fileName, bool writeHierarchy); public void WriteXml(string fileName, bool writeHierarchy);
public void WriteXml(XmlWriter writer, bool writeHierarchy); public void WriteXml(XmlWriter writer, bool writeHierarchy); public void WriteXml(XmlWriter writer, bool writeHierarchy);
public void WriteXml(XmlWriter writer); public void WriteXml(XmlWriter writer); public void WriteXml(XmlWriter writer);
public void WriteXml(TextWriter writer, bool writeHierarchy); public void WriteXml(TextWriter writer, bool writeHierarchy); public void WriteXml(TextWriter writer, bool writeHierarchy);
public void WriteXml(TextWriter writer); public void WriteXml(TextWriter writer); public void WriteXml(TextWriter writer);
public void WriteXml(TextWriter writer, XmlWriteMode mode); public void WriteXml(TextWriter writer, XmlWriteMode mode); public void WriteXml(TextWriter writer, XmlWriteMode mode);
public void WriteXml(XmlWriter writer, XmlWriteMode mode); public void WriteXml(XmlWriter writer, XmlWriteMode mode); public void WriteXml(XmlWriter writer, XmlWriteMode mode);
public void WriteXml(Stream stream, XmlWriteMode mode, bool writeHierarchy); public void WriteXml(Stream stream, XmlWriteMode mode, bool writeHierarchy); public void WriteXml(Stream stream, XmlWriteMode mode, bool writeHierarchy);
public void WriteXml(XmlWriter writer, XmlWriteMode mode, bool writeHierarchy); public void WriteXml(XmlWriter writer, XmlWriteMode mode, bool writeHierarchy); public void WriteXml(XmlWriter writer, XmlWriteMode mode, bool writeHierarchy);
public void WriteXml(string fileName, XmlWriteMode mode); public void WriteXml(string fileName, XmlWriteMode mode); public void WriteXml(string fileName, XmlWriteMode mode);
public void WriteXml(string fileName, XmlWriteMode mode, bool writeHierarchy); public void WriteXml(string fileName, XmlWriteMode mode, bool writeHierarchy); public void WriteXml(string fileName, XmlWriteMode mode, bool writeHierarchy);
public void WriteXml(Stream stream, bool writeHierarchy); public void WriteXml(Stream stream, bool writeHierarchy); public void WriteXml(Stream stream, bool writeHierarchy);
public void WriteXml(Stream stream); public void WriteXml(Stream stream); public void WriteXml(Stream stream);
public void WriteXml(TextWriter writer, XmlWriteMode mode, bool writeHierarchy); public void WriteXml(TextWriter writer, XmlWriteMode mode, bool writeHierarchy); public void WriteXml(TextWriter writer, XmlWriteMode mode, bool writeHierarchy);
public void WriteXmlSchema(TextWriter writer, bool writeHierarchy); public void WriteXmlSchema(TextWriter writer, bool writeHierarchy); public void WriteXmlSchema(TextWriter writer, bool writeHierarchy);
public void WriteXmlSchema(XmlWriter writer); public void WriteXmlSchema(XmlWriter writer); public void WriteXmlSchema(XmlWriter writer);
public void WriteXmlSchema(XmlWriter writer, bool writeHierarchy); public void WriteXmlSchema(XmlWriter writer, bool writeHierarchy); public void WriteXmlSchema(XmlWriter writer, bool writeHierarchy);
public void WriteXmlSchema(string fileName); public void WriteXmlSchema(string fileName); public void WriteXmlSchema(string fileName);
public void WriteXmlSchema(string fileName, bool writeHierarchy); public void WriteXmlSchema(string fileName, bool writeHierarchy); public void WriteXmlSchema(string fileName, bool writeHierarchy);
public void WriteXmlSchema(TextWriter writer); public void WriteXmlSchema(TextWriter writer); public void WriteXmlSchema(TextWriter writer);
public void WriteXmlSchema(Stream stream, bool writeHierarchy); public void WriteXmlSchema(Stream stream, bool writeHierarchy); public void WriteXmlSchema(Stream stream, bool writeHierarchy);
public void WriteXmlSchema(Stream stream); public void WriteXmlSchema(Stream stream); public void WriteXmlSchema(Stream stream);
protected virtual DataTable CreateInstance(); protected virtual DataTable CreateInstance(); protected virtual DataTable CreateInstance();
protected virtual Type GetRowType(); protected virtual Type GetRowType(); protected virtual Type GetRowType();
protected virtual XmlSchema GetSchema(); protected virtual XmlSchema GetSchema(); protected virtual XmlSchema GetSchema();
protected virtual DataRow NewRowFromBuilder(DataRowBuilder builder); protected virtual DataRow NewRowFromBuilder(DataRowBuilder builder); protected virtual DataRow NewRowFromBuilder(DataRowBuilder builder);
protected virtual void OnPropertyChanging(PropertyChangedEventArgs pcevent); protected virtual void OnPropertyChanging(PropertyChangedEventArgs pcevent); protected virtual void OnPropertyChanging(PropertyChangedEventArgs pcevent);
protected virtual void OnRemoveColumn(DataColumn column); protected virtual void OnRemoveColumn(DataColumn column); protected virtual void OnRemoveColumn(DataColumn column);
protected virtual void OnRowChanged(DataRowChangeEventArgs e); protected virtual void OnRowChanged(DataRowChangeEventArgs e); protected virtual void OnRowChanged(DataRowChangeEventArgs e);
protected virtual void OnRowChanging(DataRowChangeEventArgs e); protected virtual void OnRowChanging(DataRowChangeEventArgs e); protected virtual void OnRowChanging(DataRowChangeEventArgs e);
protected virtual void OnRowDeleted(DataRowChangeEventArgs e); protected virtual void OnRowDeleted(DataRowChangeEventArgs e); protected virtual void OnRowDeleted(DataRowChangeEventArgs e);
protected virtual void OnRowDeleting(DataRowChangeEventArgs e); protected virtual void OnRowDeleting(DataRowChangeEventArgs e); protected virtual void OnRowDeleting(DataRowChangeEventArgs e);
protected virtual void OnTableCleared(DataTableClearEventArgs e); protected virtual void OnTableCleared(DataTableClearEventArgs e); protected virtual void OnTableCleared(DataTableClearEventArgs e);
protected virtual void OnTableClearing(DataTableClearEventArgs e); protected virtual void OnTableClearing(DataTableClearEventArgs e); protected virtual void OnTableClearing(DataTableClearEventArgs e);
protected virtual void OnTableNewRow(DataTableNewRowEventArgs e); protected virtual void OnTableNewRow(DataTableNewRowEventArgs e); protected virtual void OnTableNewRow(DataTableNewRowEventArgs e);
protected virtual void ReadXmlSerializable(XmlReader reader); protected virtual void ReadXmlSerializable(XmlReader reader); protected virtual void ReadXmlSerializable(XmlReader reader);
protected internal DataRow NewRowArray(int size); protected internal DataRow NewRowArray(int size); protected internal DataRow[] NewRowArray(int size);
protected internal virtual void OnColumnChanged(DataColumnChangeEventArgs e); protected internal virtual void OnColumnChanged(DataColumnChangeEventArgs e); protected internal virtual void OnColumnChanged(DataColumnChangeEventArgs e);
protected internal virtual void OnColumnChanging(DataColumnChangeEventArgs e); protected internal virtual void OnColumnChanging(DataColumnChangeEventArgs e); protected internal virtual void OnColumnChanging(DataColumnChangeEventArgs e);

一致:80 / 差:0

■ 合計

完全に一致!

一致:122 / 差:0
という結果(多分)になりました。

古くからの .NET Framework ユーザーには DataTable を愛している方も多いですが、これなら安心ですね!

ただし、今回は DataTable クラスだけを比較しています。実は、DataTable に関する機能はそれだけでは語り切れないのでそのあたりは、今後また確認して行こうと思います。

Windows Mixed Reality 対応ノート PC を買いました

あまり自慢できる PC ではありませんが、Mixed Reality に対応した PC を購入しました。

■ 目的

Windows Mixed Reality アプリ開発入門書籍が出たことが理由です。
忙しさを言い訳に Mixed Reality 触るのを後回しにし続けてきましたが、やはり書籍が出るとやらないといけない気持ちが強まります。
とにかく外で使うこともできて開発のできる PC をということで今日入試ました。

■ 購入した PC

マウスコンピューターのノート PC です。店頭で購入したので、まさに完全に同じ型番のモデルをサイトで見つけることができませんでしたが、このシリーズです。

メモリ16GB、SSD256GBとHDD1TB ので GPU は GeForce® MX150 (2GB)。15.6インチサイズで重量は 2.4 kg と普段使いには厳しいですが、とりあえず様々な開発環境を入れる容量と気持ち程度の GPU を積んでいることで選択しました。
あと価格ですね。およそ 13万円。他メーカーだと平気で 20 万円超えたりするので。
メインのノート PC を別に持っているのにもう一台高額な PC はさすがに気持ち的に難しく、気軽に買える価格の安いマシンで済ませてみました。

■ 動作チェック

とりあえず起動して合砂確認だけしてみました。 Mixed Reality ポータルを起動し対応のチェック、すべて〇です。GPU を積んでいないとそこは△になるので、気持ち程度でも GPU は偉大です。
MR ヘッドセットを接続して起動。ポータルが動作しました。

とりあえず、外で MR 開発が行える力を手に入れました。正直普段持ち歩ける PC ではないので突発では難しいですが、予定があれば頑張って持ち運べます。
東京の東の方で MR 開発の集まりなどが開催されるとうれしいです。この PC を持って参加したいと思います。

Adaptive Code ~ C#実践開発手法 第2版 読書会 #1 を開催しました。

■ Adaptive Code ~ C#実践開発手法 第2版 読書会

「Adaptive Code ~ C#実践開発手法 第2版」を読んでみる会です。
(ISBN:9784822253547 https://shop.nikkeibp.co.jp/front/commodity/0000/P53540/ )

■ 概要

交代で音読するスタイルで行います。
読書会への参加のお試し用に、「Adaptive Code ~ C#実践開発手法 第2版」を数冊用意しています。
初心者の方も気楽にご参加ください。一緒に勉強しましょう!

■ 読書ページ

・今回
今回は初回なので最初から読み、24ページまで読み進めました。

・次回
24ページ「1.3.2 | チャートと指針」から読み始めましう。

■ 今回の概要

第1部 アジャイル開発のフレームワーク
 第1章 スクラムの紹介

の前半部分を読みました。

まだ、Adaptive Code の前提となる「アジャイルでは、変更は歓迎され、変更に適応することが誰にでも認められる」ことの解説が続いています。C# コードは全く出てこないので、そこは今後のお楽しみです。
しかし、なぜその技法を使うのかは大事なことです。未経験の技法に一切挑戦しないよりは、「良くわからないけどやってみたい」だとしても挑戦した方が良いことは間違いありませんが、「なぜその技法を使うのか」を分かって挑戦することがベストであることは間違いないと思います。流さずきっちり真名で行こうと思います

今回の範囲では、アジャイルが何をもたらしてくれるのか、ウォーターフォールの限界とアジャイルで得られるもの、スクラムボードと技術的負債あたりがトピックだったでしょうか。

これは私の個人的な希望ですが、技術的負債の説明部分は技術的負債を知らない業界の方すべてに読んでもらいたいですね。
きっと業界の悪習を断ち切る力になると思います。

■ .NET 読書会

.NET 系の書籍を読む会です。
.NET 系の書籍はあまり数は出版されませんが、どれも素晴らしいものばかりです。しかしこの素晴らしさは、書籍の厚さやレベルの高さという面もあり誰でもいつでも気軽にとは言い難い場合もあります。また、書籍を読んでの自分の解釈だけでなく、同じ書籍を読んだ他者の解釈を聞くことも非常に大きな学びがあると思います。
そんな .NET 系の読書を支援するコミュニティです。現在の活動としては定期的に、connpass 上で読書会イベントを公開しています。

■ 次回予定

次回は 07/09(月)に開催予定です。

ご都合のつく方、ぜひ遊びに来てください。

Xamarin 入門者ハンズオン (DevDays ハンズオン) を Xamarin.Forms.WPF でやってみた。

■ 初心者向けXamarinハンズオン

Xamarin は非常に入門者にやさしく Japan Xamarin Users Group 主催の「初心者向けXamarinハンズオン」が4~5ヵ月くらいの間隔で行われています。
現在の日本での Xamarin の入り口と言っていいでしょう。

つまり、日本での Xamarin の基本と言える、ということは新しいプラットフォームがあるなら当然このハンズオンに新しいプラットフォームで挑んでみるわけです。

■ ハンズオン資料

前述のイベントにはぜひ参加してもらいたいところですが、残念ながらお時間の都合のつかない方や遠方の方もご安心ください。
資料は今話題の GitHub というサイトで公開されています。

こちらの資料に沿って学べますので独学でも全然 OK です。

■ 完成プロジェクトについて

大変申し訳ないのですが、完成プロジェクトは公開していません。
前述の日本語訳プロジェクトにはライセンスが明示されているのですが、ソースの置かれている本家にぱっと見で見つけられなかったもので。。。

■ 完成

まず最初に完成写真から。

1ページ目
f:id:rksoftware:20180629013423j:plain

2ページ目
f:id:rksoftware:20180629013439j:plain

完全に一致
f:id:rksoftware:20180629013456j:plain

完璧に対応していますね。すばらしい。

■ 制約

見た目は完璧でしたが、動作はまだ不完全です。

・読み上げるボタン
NotImplementedException が発生します。読み上げ機能は、Xamarin.Forms 本体の機能ではな追加のプラグインの導入という形で実現されています。
このプラグインが、WPF に未対応ということですね。それでもビルドはできるようにまでは対応してくれています。ビルドできないと試せないですから、これはありがたいことです。

・ウェブサイトに移動ボタン
押しても何も起きません。中身まではまだ終えていないので何が起きているのかはわかりませんが、未実装ということなのでしょう。
こちらも、それでもビルドはできるようにまでは対応してくれています。ありがたいです。

■ 作業手順

WPF 版の作業手順は単純です。

・通常のハンズオン手順で、Android・iOS・UWP を完成させる

・Xamrin.Forms.WPF でのデスクトップアプリの作り方通りに WPF プロジェクトを追加する

・実行する

たったこれだけの簡単な仕事です。これだけで WPF のデスクトップアプリになってしまいます。すばらしい。

■ ソースコード

特別なものは何もないのであまり意味はありませんが、WPF プロジェクト内のソースコードも記載しておきます。

App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="OpenTK" publicKeyToken="bad199fe84eb3df4" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

App.xaml

<Application x:Class="DevDaysSpeakers.WPF.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:DevDaysSpeakers.WPF"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>

App.xaml.cs

using System.Windows;

namespace DevDaysSpeakers.WPF
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
    }
}

MainWindow.xaml

<xf:FormsApplicationPage x:Class="DevDaysSpeakers.WPF.MainWindow"
        xmlns:xf="clr-namespace:Xamarin.Forms.Platform.WPF;assembly=Xamarin.Forms.Platform.WPF"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DevDaysSpeakers.WPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        
    </Grid>
</xf:FormsApplicationPage>

MainWindow.xaml.cs

namespace DevDaysSpeakers.WPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Xamarin.Forms.Platform.WPF.FormsApplicationPage
    {
        public MainWindow()
        {
            InitializeComponent();

            Xamarin.Forms.Forms.Init();
            LoadApplication(new DevDaysSpeakers.App());
        }
    }
}

OpenTK.dll.config

<configuration>
  <dllmap os="linux" dll="opengl32.dll" target="libGL.so.1"/>
  <dllmap os="linux" dll="glu32.dll" target="libGLU.so.1"/>
  <dllmap os="linux" dll="openal32.dll" target="libopenal.so.1"/>
  <dllmap os="linux" dll="alut.dll" target="libalut.so.0"/>
  <dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
  <dllmap os="linux" dll="libX11" target="libX11.so.6"/>
  <dllmap os="linux" dll="libXi" target="libXi.so.6"/>
  <dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
  <dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
  <dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
  <dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
  <dllmap os="osx" dll="libGLES.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
  <dllmap os="osx" dll="libGLESv1_CM.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
  <dllmap os="osx" dll="libGLESv2.dll" target="/System/Library/Frameworks/OpenGLES.framework/OpenGLES" />
  <dllmap os="osx" dll="opencl.dll" target="/System/Library/Frameworks/OpenCL.framework/OpenCL"/>
  <dllmap os="osx" dll="SDL2.dll" target="libSDL2.dylib"/>
  <!-- XQuartz compatibility (X11 on Mac) -->
  <dllmap os="osx" dll="libGL.so.1" target="/usr/X11/lib/libGL.dylib"/>
  <dllmap os="osx" dll="libX11" target="/usr/X11/lib/libX11.dylib"/>
  <dllmap os="osx" dll="libXcursor.so.1" target="/usr/X11/lib/libXcursor.dylib"/>
  <dllmap os="osx" dll="libXi" target="/usr/X11/lib/libXi.dylib"/>
  <dllmap os="osx" dll="libXinerama" target="/usr/X11/lib/libXinerama.dylib"/>
  <dllmap os="osx" dll="libXrandr.so.2" target="/usr/X11/lib/libXrandr.dylib"/>
</configuration>

packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.Azure.Mobile.Client" version="4.0.2" targetFramework="net461" />
  <package id="Microsoft.Azure.Mobile.Client.SQLiteStore" version="4.0.2" targetFramework="net461" />
  <package id="Newtonsoft.Json" version="11.0.2" targetFramework="net461" />
  <package id="OpenTK" version="2.0.0" targetFramework="net461" />
  <package id="OpenTK.GLControl" version="1.1.2349.61993" targetFramework="net461" />
  <package id="SQLitePCLRaw.bundle_green" version="1.1.2" targetFramework="net461" />
  <package id="SQLitePCLRaw.core" version="1.1.2" targetFramework="net461" />
  <package id="SQLitePCLRaw.lib.e_sqlite3.linux" version="1.1.2" targetFramework="net461" />
  <package id="SQLitePCLRaw.lib.e_sqlite3.osx" version="1.1.2" targetFramework="net461" />
  <package id="SQLitePCLRaw.lib.e_sqlite3.v110_xp" version="1.1.2" targetFramework="net461" />
  <package id="SQLitePCLRaw.provider.e_sqlite3.net45" version="1.1.2" targetFramework="net461" />
  <package id="WpfLightToolkit" version="1.0.1" targetFramework="net461" />
  <package id="Xam.Plugins.TextToSpeech" version="4.0.0.7" targetFramework="net461" />
  <package id="Xamarin.Forms" version="3.0.0.561731" targetFramework="net461" />
  <package id="Xamarin.Forms.Platform.WPF" version="3.0.0.561731" targetFramework="net461" />
</packages>

■ もう試せる

いつもやってるハンズオンにも完全に対応いうことで、Xamarin.Forms.WPF が普通にデスクトップアプリ開発に使える期待がまた一つ高まりました。