如何提供將我的課程轉換爲其他類型的支持?例如,如果我有自己的管理byte[]
的實現,並且我想讓人們將我的課程投放到只返回私人成員的byte[]
,那麼我該怎麼做?如何爲我的課程提供自定義演員支持?
通常的做法是讓他們也把這個字符串轉換成字符串,或者我應該重寫ToString()
(或兩者)?
如何提供將我的課程轉換爲其他類型的支持?例如,如果我有自己的管理byte[]
的實現,並且我想讓人們將我的課程投放到只返回私人成員的byte[]
,那麼我該怎麼做?如何爲我的課程提供自定義演員支持?
通常的做法是讓他們也把這個字符串轉換成字符串,或者我應該重寫ToString()
(或兩者)?
您需要覆蓋轉換運算符,使用implicit
或explicit
,具體取決於您希望用戶必須投射它還是希望它自動發生。通常,一個方向將始終有效,這就是您使用implicit
的地方,而另一個方向有時可能會失敗,這就是您使用explicit
的地方。
public static implicit operator byte[] (MyType x)
{
byte[] ba = // put code here to convert x into a byte[]
return ba;
}
- :
的語法是這樣的(>byte[]
永遠是可行的MyType
)
public static implicit operator dbInt64(Byte x)
{
return new dbInt64(x);
}
或
public static explicit operator Int64(dbInt64 x)
{
if (!x.defined)
throw new DataValueNullException();
return x.iVal;
}
對於你的榜樣,從您的自定義類型說
or
public static explicit operator MyType(byte[] x)
{
if (!CanConvert)
throw new DataValueNullException();
// Factory to convert byte[] x into MyType
MyType mt = MyType.Factory(x);
return mt;
}
我寧願有一些方法可以做到這一點,而不是重載演員操作。
見explicit and implicit c#但要注意,從例如,使用顯式的方法,如果你這樣做:
string name = "Test";
Role role = (Role) name;
然後一切都很好;但是,如果你使用:
object name = "Test";
Role role = (Role) name;
現在你會得到一個InvalidCastException因爲字符串不能轉換到角色,爲什麼,編譯器僅查找在根據自己的編譯型編譯時隱式/顯式轉換。在這種情況下,編譯器將名稱視爲對象而不是字符串,因此不使用Role的重載操作符。
看看你鏈接到的例子,它似乎在每個演員陣容上創建對象的新實例。任何想法如何對類的當前成員進行get/set類型的操作? – esac
您可以使用explicit
或implicit
關鍵字在您的類上聲明轉換運算符。
作爲一般的經驗法則,當轉換不可能失敗時,應該只提供implicit
轉換運算符。轉換可能失敗時使用explicit
轉換運算符。
public class MyClass
{
private byte[] _bytes;
// change explicit to implicit depending on what you need
public static explicit operator MyClass(byte[] b)
{
MyClass m = new MyClass();
m._bytes = b;
return m;
}
// change explicit to implicit depending on what you need
public static explicit operator byte[](MyClass m)
{
return m._bytes;
}
}
使用explicit
意味着你的類的用戶將需要做一個明確的轉換:
byte[] foo = new byte[] { 1, 2, 3, 4, 5 };
// explicitly convert foo into an instance of MyClass...
MyClass bar = (MyClass)foo;
// explicitly convert bar into a new byte[] array...
byte[] baz = (byte[])bar;
使用implicit
意味着你的類的用戶不需要進行顯式轉換,這一切透明地發生:
byte[] foo = new byte[] { 1, 2, 3, 4, 5 };
// imlpicitly convert foo into an instance of MyClass...
MyClass bar = foo;
// implicitly convert bar into a new byte[] array...
byte[] baz = bar;
對於自定義投射支持,您需要提供演員操作符(顯式或隱式)。 EncodedString類的以下示例是使用自定義編碼的字符串的簡單實現(如果必須處理巨大的字符串並遇到內存消耗問題,可能會很有用,因爲.Net字符串是Unicode - 每個字符需要2個字節的內存 - 和EncodedString每個字符可以佔用1個字節)。
EncodedString可以轉換爲byte []和System.String。 代碼中的註釋揭示了一些光線,並解釋了隱式轉換可能會導致危險的示例。
通常您首先需要非常好的理由來聲明任何轉換運算符,因爲。
更多資料請訪問MSDN。
class Program
{
class EncodedString
{
readonly byte[] _data;
public readonly Encoding Encoding;
public EncodedString(byte[] data, Encoding encoding)
{
_data = data;
Encoding = encoding;
}
public static EncodedString FromString(string str, Encoding encoding)
{
return new EncodedString(encoding.GetBytes(str), encoding);
}
// Will make assumption about encoding - should be marked as explicit (in fact, I wouldn't recommend having this conversion at all!)
public static explicit operator EncodedString(byte[] data)
{
return new EncodedString(data, Encoding.Default);
}
// Enough information for conversion - can make it implicit
public static implicit operator byte[](EncodedString obj)
{
return obj._data;
}
// Strings in .Net are unicode so we make no assumptions here - implicit
public static implicit operator EncodedString(string text)
{
var encoding = Encoding.Unicode;
return new EncodedString(encoding.GetBytes(text), encoding);
}
// We have all the information for conversion here - implicit is OK
public static implicit operator string(EncodedString obj)
{
return obj.Encoding.GetString(obj._data);
}
}
static void Print(EncodedString format, params object[] args)
{
// Implicit conversion EncodedString --> string
Console.WriteLine(format, args);
}
static void Main(string[] args)
{
// Text containing russian letters - needs care with Encoding!
var text = "Привет, {0}!";
// Implicit conversion string --> EncodedString
Print(text, "world");
// Create EncodedString from System.String but use UTF8 which takes 1 byte per char for simple English text
var encodedStr = EncodedString.FromString(text, Encoding.UTF8);
var fileName = Path.GetTempFileName();
// Implicit conversion EncodedString --> byte[]
File.WriteAllBytes(fileName, encodedStr);
// Explicit conversion byte[] --> EncodedString
// Prints *wrong* text because default encoding in conversion does not match actual encoding of the string
// That's the reason I don't recommend to have this conversion!
Print((EncodedString)File.ReadAllBytes(fileName), "StackOverflow.com");
// Not a conversion at all. EncodingString is instantiated explicitly
// Prints *correct* text because encoding is specified explicitly
Print(new EncodedString(File.ReadAllBytes(fileName), Encoding.UTF8), "StackOverflow.com");
Console.WriteLine("Press ENTER to finish");
Console.ReadLine();
}
}
謝謝,正是我期待的。 – esac