C#: null ãã class 㨠null ããªã struct ãããã®å¯è½æ§ããã object ã as<T> ãããå ´åã®éçãããã㯠C# ãããçµè«
// ããã¯ã³ã³ãã¤ã«ã§ããªã(´ã»Ïã»ï½) // object -> T static public T As<T>( object o ) { return o as T; }
// as T ã§ããããã«ã¯ T ã« class å¶ç´ãå¿ è¦ãããã¯ã³ã³ãã¤ã«ã§ããããæå¾ åä½ãããããããªãã // object(class=nullããä½ã) -> T static public T As<T>( object o ) where T: class { return o as T; }
// ãã㯠As<T> ãæå¾ åä½ããã object a = "Яï¼ãã¼ï¼"; var aa = As<string>( a ); Console.Write( aa );
// ãã㯠As<T> ãã³ã³ãã¤ã«ã§ããªãããæå¾ åä½ã§ããªãã object b = 4649; var bb = As<int>( b ); // <-- oops! Console.Write( bb );
// ããã¯ã³ã³ãã¤ã«ã§ããªã(´ã»Ïã»ï½) static public T? AsNullable<T>( object o ) { return o as T?; }
// as T? ã§ããããã«ã¯ T ã« struct å¶ç´ãå¿ è¦ãããã¯ã³ã³ãã¤ã«ã§ããããæå¾ åä½ãããããããªãã static public T? AsNullable<T>( object o ) where T: struct { return o as T?; }
object b = 4649; var bb = AsNullable<int>( b ); // int? åã«ãªãã // æé»çã« int åã®ããªãå¾æ㪠struct ãã©ãããã class çã«æ¯ãèãã Console.WriteLine( $"bb={bb} (bb==null)={bb==null}" ); // null ãã bb = null; Console.WriteLine( $"bb={bb} (bb==null)={bb==null}" );
// ã§ã(´ã»Ïã»ï½)⦠int bbb = bb; // <-- oops! int? 㯠int ã«ãªããªãã®ã§ã³ã³ãã¤ã«ã¨ã©ã¼ã
// ãint? -> int ã¾ãã¯ç¡ãã£ãæã® int ãªè£å©è¦å¡ãç¨æããªãã§ãã int bbb = bb ?? -1;
// ã¤ã¾ãâ¦(´ã»Ïã»ï½) ãããªã object ãã int ã¨ã struct 㪠T ã¸ã As<T> ã§ãããä¸å¿ã static public T As<T>( object o, T default_value ) where T : struct { return o as T? ?? default_value; }
// ä¸å¿ãæå¾ åä½ããã object b = 4649; int bbb = As( b, -1 ); // åãã©ã¡ã¼ã¿ã¼ã¯ç¬¬2å®å¼æ°ããæ¨è«ã§ããã®ã§çç¥ããããã
// ã¤ã¾ã⦠2ã¤ãªã¼ãã¼ãã¼ããã¦ããã¦â¦ // 対 class ç¨ As<T> static public T As<T>( object o ) where T : class { return o as T; } // 対 struct ç¨ As<T> static public T As<T>( object o, T default_value ) where T : struct { return o as T? ?? default_value; }
// int, float, double, string; string 㯠class, ãã®ã»ã㯠struct var os = new object[]{ 123, 1.23, 12.3f, "hoge" }; // ä¸å¿ã ã©ã¡ãã«ã As<T> ã§ããªããã¨ããªãâ¦(´ã»Ïã»ï½) foreach ( var o in os ) Console.WriteLine( $"{As( o, -1 )}, {As( o, -2.0 )}, {As( o, -3.0f )}, {As<string>( o )}" );
// ãããªããåºããæå¾ åä½ã¨ãããå ´åããããã©ãè¨ããªãå ´åããã(´ã»Ïã»ï½) // åå¤å®ãå³å¯éã㦠As ã¨ãããã Is Then ã£ã¦æãã ã(´ã»Ïã»ï½) 123, -2, -3, -1, 1.23, -3, -1, -2, 12.3, -1, -2, -3, hoge
ã§ããã® As<T>
㯠As<T>
ã使ãå®è£
è
ã object
ã®ä¸èº«ã class
ã struct
ãç¥ã£ã¦ããªãã¨ä½¿ããªããããããããã§ãä¸å¿ããæããªã(´ã»Ïã»ï½)
// ããã¯ãã¡ãã³ã³ãã¤ã«ã¨ã©ã¼ãC#ã®ã¡ã½ããã®ã·ã°ããã£ã¼ã« where å¥ã¯å«ã¾ããªãã®ã§åãã·ã°ããã£ã¼ã®ã¡ã½ããã®éè¤å®ç¾©ã static public T As<T>( object o, T default_value ) where T : class { return o as T ?? default_value; } static public T As<T>( object o, T default_value ) where T : struct { return o as T? ?? default_value; }
// ããã¯æå¾ åä½ãã¡ãããã·ã°ããã£ã¼ã¯ç°ãªãäºã«ãªã£ã¦ã³ã³ãã¤ã«ã§ãããããã£ãã® os 㨠As<T> ã®ä½¿ãæ¹ãªãæå¾ åä½ããã static public T As<T>( object o, object default_value = null ) where T : class { return o as T ?? default_value as T; } static public T As<T>( object o, T default_value ) where T : struct { return o as T? ?? default_value; }
// ã§ããããããã¨æ»ã¬ã®ã§ãæå¾ åä½ãã¡ãããã ã£ãã var os = new object[]{ 123, 1.23, 12.3f, "hoge" }; foreach ( var o in os ) Console.WriteLine( $"{As( o, -1 )}, {As( o, -2.0 )}, {As( o, -3.0f )}, {As( o, "fuga" )}" ); // <-- æå¾ã® As ãæ¸ãæ¹ãçµ±ä¸ãã¦ã¿ã¡ããã¨æ»ã¬ã
As<T>( o, "fuga" )
㯠class
å¶ç´ã®æ¹ãå¼ã°ãã¦æ¬²ãããã ãã©ããããªããã°ã©ãã¼ã®ãæ°æã¡ã¯è¨èªä»æ§ã¯çµãã§ãããµãåä½ãã¦ãããªããããæ»ã¬ã
// ãã¼ãããã¨èããçµæããã©ãçãã C# ã®éçã«ç¡çãããªã As<T> ãã¡ static public T AsClass<T>( object o ) where T : class { return o as T; } static public T? AsStruct<T>( object o ) where T : struct { return o as T?; }
// ã¤ãã§ã«ãã¾ãã(double)34.56 ã (int)35 ã« As ãããã¨ããã¼ãã¼å ´åç¨ static public T AsConvertible<T>( object o ) where T : IConvertible { return (T)Convert.ChangeType( o, typeof(T) ); }
ã¾ãâ¦ãä¸å¿èãã¦ã¯ã¿ã¾ããããå
é¨çã«ã¯ AsClass<T>
ã AsStruct<T>
ã試ããçµæã (TC,TS?)
ãªã¿ãã«ã§è¿ãã¦â¦ã¨ãã class X<TC,TS>
ãªæã㧠class
㪠object
㨠struct?
㪠object
ãããããã£ã¼ã§ä¿æãã¤ã¤ã operator
群, Equals
, GetHashCode
, GetType
ããããªã«å®è£
ããèãã©ããã¼ã As<T>
ã§è¿ããã¦â¦ã¨ãããã£ãå®å¼æ°ã§åãã©ã¡ã¼ã¿ã¼ç¸å½ã®â¦ã¨ãã
ã§ãã C# ã®è¨èªä»æ§ã®éçããããªç²ãã¦ä¿å®æ§ãæªãããªä½ããå¿
æ»ã«ä½ã£ã¦ã©ãã«ãããã§ãâ¦ã¨æãããããããããªãã¨âã® AsClass
, AsStruct
, AsConvertible
ãä½ãã®é¨åã« internal
ã§ä½¿ãããã§ãªããã°ãã»ã¨ãã©åå¨ä¾¡å¤ããªãã©ãããç¡é§ãªããã§â¦ã
// å®è¡æã«è¬ã® object ããããããããããâ¦ã£ã¦å¦çããããªã(´ã»Ïã»ï½) void f( object o ) { switch ( o ) { case IConvertible convertible: // ... ç¥ case MyStructX sx: // ... ç¥ case MyClass1 c1: // ... ç¥ case MyClass2 c2: // ... ç¥ } }
ã¡ã½ããã§ãã£ã¹ããããããå æ¬çã«å¦çãããã£ãããä½ãã¨ããèãããããããããå®éåé¡ããããä¸çªæ¸ãã®ãä¿å®ããã®ãããð