關于類型轉換,C#與JAVA最大的不同在于C#有struct,而JAVA則沒有這玩意。于是乎在C#中泛型類型轉換就有一下代碼(僅限struct結構)。另外一個較小的差異呢則是在C#中各struct類型都帶有TryParse方法,當然,2.0以后(包括2.0)才有。
namespace DObject.DType
{
/// <summary>
/// 類型轉換幫助類,靜態方法實現。加入了緩存機制,減少反射次數。
/// </summary>
public static class StaticConvertor
{
private const string CONVERTMETHOD = "TryParse";
private static Dictionary<System.Type, MethodInfo> map = new Dictionary<System.Type, MethodInfo>(20);
private static MethodInfo prepareMethod(System.Type type)
{
lock (map)
{
if (!map.ContainsKey(type))
{
System.Type[] typeArray = new System.Type[2];
typeArray.SetValue(typeof(string), 0);
typeArray.SetValue(type.GetType().MakeByRefType(), 1);
MethodInfo method = type.GetType().GetMethod(CONVERTMETHOD, typeArray);
if (method != null)
{
map.Add(type, method);
}
else
return null;
}
return map[type];
}
} //end prepareMethod
/// <summary>
/// 轉換方法
/// </summary>
/// <typeparam name="T">轉換后類型</typeparam>
/// <param name="raw">原始對象</param>
/// <param name="defaultValue">默認值</param>
/// <param name="convertSuccessful">是否轉換成功</param>
/// <returns>返回值</returns>
public static T Convert<T>(object raw, T defaultValue, out bool convertSuccessful) where T : struct
{
convertSuccessful = false;
if (raw == null) //失敗
return defaultValue;
else if (raw is T) //成功
{
convertSuccessful = true;
return (T)raw;
}
else
{
try
{
object[] parms = new object[2];
parms[0] = raw.ToString();
parms[1] = 0;
bool isparser = (bool)prepareMethod(typeof(T)).Invoke(null, parms);
if (isparser) //成功
{
convertSuccessful = true;
return (T)parms[1];
}
}
catch
{
}
return defaultValue;
}
} //end Convert<T>
}
}
以上代碼的寫法,適合DateTime,Int32,Int64,Int16,byte,bool等。只有是struct結構,并且有TryParse方法就可以使用。而使用起來呢也很簡單,如以下代碼
namespace DObject.DType
{
/// <summary>
/// Int32類型保證
/// </summary>
public class DInt32 : DObject, IValuetable<Int32>, IConvertSuccess
{
private int target;
private int defaultValue = -1;
/// <summary>
/// 構造函數,對象初始化時,就執行轉換
/// </summary>
/// <param name="o"></param>
public DInt32(object o)
: base(o)
{
target = StaticConvertor.Convert<int>(base.raw, defaultValue, out convertSuccessful);
}
public static implicit operator DInt32(DType type)
{
return new DInt32(type.RawObject);
}
private bool convertSuccessful;
/// <summary>
/// 返回轉換值
/// </summary>
/// <returns>返回轉換值,如果轉換成功則返回值;轉換失敗返回默認值 -1</returns>
public int Value()
{
return Value(defaultValue);
}
/// <summary>
/// 返回轉換值
/// </summary>
/// <param name="defaultValue">默認值</param>
/// <returns>返回轉換值,如果轉換成功則返回值;轉換失敗返回默認值</returns>
public int Value(int defaultValue)
{
if (convertSuccessful)
return target;
return defaultValue;
}
/// <summary>
/// 是否轉換成功
/// </summary>
public bool ConvertSuccess
{
get { return convertSuccessful; }
}
}
}
/// <summary>
/// 構造類型,為內置類型提供構造參數。
/// <example>
/// DInt32 int32 = DType.Default("123");
/// </example>
/// </summary>
public class DType
{
private object o;
private DType(object o)
{
this.o = o;
}
/// <summary>
/// 提供對象構造參數
/// </summary>
/// <param name="o"></param>
/// <returns></returns>
public static DType Default(object o)
{
return new DType(o);
}
/// <summary>
/// 原始對象
/// </summary>
public object RawObject
{
get { return o; }
}
}
使用起來也是簡單:
DInt32 int32 = DType.Default("123");
int val = int32.Value();
Java里就沒這樣的了,使用try捕獲錯誤并非想要的。java里沒有struct,但是有個類型Number確是可以使用。當然,這就不能像C#一樣將亂七八糟的東西都整一塊了,要分開來處理了。
/**
*
* @author yurow
*/
public class DNumber extends DObject {
/**
* Create new instance of DNumber
*/
protected DNumber() {
super();
}
protected DNumber(Object obj)
{
super(obj);
}
protected Boolean isconvert;
public Number Convert(Number defaultValue) {
isconvert = false;
if (obj == null) {
return defaultValue;
} else if (obj instanceof Number) {
isconvert = true;
return Number.class.cast(obj);
} else {
return defaultValue;
}
}
}
/**
*
* @author yurow
*/
public class DInt32 extends DNumber {
/**
* Create new instance of DInt32
*/
protected DInt32() {
super();
}
protected DInt32(Object obj) {
super(obj);
}
public static DInt32 newInt32(Object obj) {
return new DInt32(obj);
}
public int Convert()
{
return super.Convert(-1).intValue();
}
}
可以看出,JAVA的類型邏輯層次劃分比C#要細致,處理起來當然要復雜一些。可見粒度并非越細越好。貧道看來JAVA傾向于按邏輯劃分,而C#傾向于按內存布局劃分。