簡體   English   中英

在運行時確定是否允許強制轉換(C#)

[英]Determine at runtime if a cast is allowed (C#)

我有一個帶有一系列接受各種數據類型的方法的C#包裝器類:

public class MyClass
{
    public void ProcessString(string Value) { // implementation }
    public void ProcessInt(int? Value) { // implementation }\
    public void ProcessOther(MyClass Value) { // implementation }
}

我現在想添加一個通用的ProcessObject()方法,以避免在調用相關的處理方法之前顯式轉換對象的需要:

public void ProcessObject(object Value)
{
    if (CanCastToString(Value)
    {
        ProcessString((string)Value);
    }
    else if (CanCastToInt(Value))
    {
        ProcessInt((int?)Value);
    }
    // etc...
}

問題是我不知道我的CanCastToInt方法應該是什么-我需要這些方法能夠變得健壯並能夠處理可空類型和其他用戶定義的類型轉換。

我怎樣才能做到這一點? 我只想知道是否可以將給定的對象強制轉換為給定的類型,即是否:

(SomeType)Value

將工作。

通常有兩種主要方法:

if (Value is SomeType)
{
    // Do something with a cast
}

要么

var v = Value as SomeType;
if (v != null)
{
    // Value was successfully cast as SomeType
}

使用結構或內部類型時,使它們可為空:

var v = Value as int?;
if (v != null)
{
    ProcessInt(v.Value);
}

您需要的is操作員。 CanCastToString(x) -> x is string

為什么不直接使用各種參數的重載直接公開您的處理API?

public class MyClass
{
    public void Process(string Value) { // implementation }
    public void Process(int Value) { // implementation }\
    public void Process(MyClass Value) { // implementation }
    public void Process(object Value) { // catch all method. Handle unknown entities, e.g. call ToString() }
}

編輯使用一些泛型魔術,您可以擁有一個單一的接口方法,一堆可以完成工作的助手方法以及一個處理極端情況的萬能方法。

public class MyClass
{
    void DoProcess(string Value) { // implementation }
    void DoProcess(int Value) { // implementation }\
    void DoProcess(MyClass Value) { // implementation }
    void DoProcess(object Value) { 
        // catch all method. Handle unknown entities, e.g. call ToString()
    }
    public void Process<T>(T value) {
       //this method will call the right overload of DoProcess depending on the compile time type of value. If there isn't a match, it goes to DoProcess(object)
       DoProcess(value);
    }
}

這樣,您可以避免對基本類型進行裝箱,並且具有更好的類型安全性。

對於所有方法,您可以嘗試使用Type.IsAssignableFrom方法。 例如:

if (typeof(short).IsAssignableFrom(Value)
    DoProcess((short)Value);
if (typeof(byte).IsAssignableFrom(Value)
    DoProcess((byte)Value);

我建議您閱讀埃里克·利珀特(Eric Lippert)關於代表性演員的文章。 希望這樣做之后,您將認識到,每種受支持的類型都有一個重載可能會更容易。 另外,您可能會意識到處理拆箱值類型可能是通往地獄的道路。

如果(與OP不同?)直到運行時您都不知道所涉及的類型,則可以嘗試采用以下形式:

http://codegoeshere.blogspot.com/2007/05/dynamic-cast-in-c.html

    public void QuickTest()
    {
        object stringObj = "string";
        object nullableInt1 = (int?)null;
        object nullableInt2 = (int?)1;
        object decimalObj = 1.5m;

        ProcessObject(stringObj);
        ProcessObject(nullableInt1);
        ProcessObject(nullableInt2);
        ProcessObject(decimalObj);
    }

    public void ProcessObject(object value)
    {
        if (value == null)
        {
            Debug.WriteLine("null");
            return;
        }


        if (value is string)
        {
            Debug.WriteLine((string)value);
            return;
        }

        string stringValue = value.ToString();

        int intTemp;
        if (int.TryParse(stringValue, out intTemp))
        {
            Debug.WriteLine(intTemp);
            return;
        }

        decimal decimalTemp;
        if (decimal.TryParse(stringValue, out decimalTemp))
        {
            Debug.WriteLine(decimalTemp);
            return;
        }
        // etc...
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM