2009-01-21 90 views
17

這是我需要做的:是否可以將變量轉換爲存儲在另一個變量中的類型?

object foo = GetFoo(); 
Type t = typeof(BarType); 
(foo as t).FunctionThatExistsInBarType(); 

能像這樣做呢?

+0

你怎麼知道這是你想上等號的最後一行左邊的字符串你的榜樣?換句話說,你打算如何處理bar,這意味着你不能使用「object bar =(object)foo;」 ? – 2009-01-21 12:29:16

+0

我不這樣做,字符串只是一個例子。我編輯了片段。 – 2009-01-21 12:58:02

回答

13

不,你不能。 C#不執行duck typing

您必須實現一個接口並對其進行轉換。

(但也有嘗試做到這一點。看看Duck Typing Project的例子。)

+0

是的,你可以。看看GvS的答案:-) – 2009-01-21 11:02:07

+1

你仍然需要實現接口(在這種情況下是IConvertible),並且知道要預先輸入的類型。 – Quassnoi 2009-01-21 11:11:13

+0

我將這個答案標記爲可接受的答案,因爲我使用了Quassnoi的建議並實現了一個接口來投射它,但GvS和shuggycouk的答案也很棒。 – 2009-01-21 14:15:00

20

可以使用Convert.ChangeType方法。

object foo = GetFoo(); 
Type t = typeof(string); 
string bar = (string)Convert.ChangeType(foo, t); 
+6

僅當對象實現IConvertible時纔有用 – Quassnoi 2009-01-21 11:03:27

4

你原來的問題是有缺陷的,你問治療變量未在編譯時已知的,但請注意,您對左側定義字符串時,你聲明你的變量類型。 C#的3.5是靜態類型。

一旦動態可用,你可以做這樣的事情:

dynamic foo = GetFoo(); 
foo.FunctionThatExistsInBarType(); 

因爲當你不知道類型是什麼,但你知道它會一直支持實例方法FunctionThatExistsInBarType();現在你不得不使用反射(或者代碼gen,這些代碼真的相當於一樣的東西,但是前面更加昂貴,後面會更快)。

// any of these can be determined at runtime 
Type t = typeof(Bar); 
string methodToCall = "FunctionThatExistsInBarType"; 
Type[] argumentTypes = new Type[0]; 
object[] arguments = new object[0]; 
object foo; 
// invoke the method - 
// example ignores overloading and exception handling for brevity 
// assumption: return type is void or you don't care about it 
t.GetMethod(methodToCall, BindingFalgs.Public | BindingFlags.Instance) 
    .Invoke(foo, arguments); 
0

只要你在編譯時知道所有需要的類型,duck typing是(在某種程度上)可能:

class BarFoo {} 
class Foo {} 
class Bar {} 

class Program 
{ 
    static void Main() 
    { 
     var foo = new Foo(); 
     var bar = new Bar(); 
     var barfoo = new BarFoo(); 

     Console.WriteLine(DoStuff(foo)); 
     Console.WriteLine(DoStuff(bar)); 
     Console.WriteLine(DoStuff(barfoo)); 

    } 

    static string DoStuff(Foo foo) { return "DoStuff(Foo foo)"; } 
    static string DoStuff(Bar bar) { return "DoStuff(Bar bar)"; } 
    static string DoStuff(Base fb) { return "DoStuff(object fb)"; } 
} 

輸出:

Dostuff(Foo foo) 
Dostuff(Bar bar); 
DoStuff(object fb); 

如果你最終實現了很多基本上完全相同的方法,考慮實現一個接口。

2

由於動態加入到C#中,我認爲我們可以這樣做:

class Program { 
    static void Main(string[] args) { 
     List<int> c = new List<int>(); 
     double i = 10.0; 
     Type intType = typeof(int); 
     c.Add(CastHelper.Cast(i, intType)); // works, no exception! 
    } 
} 

class CastHelper { 
    public static dynamic Cast(object src, Type t) { 
     var castMethod = typeof(CastHelper).GetMethod("CastGeneric").MakeGenericMethod(t); 
     return castMethod.Invoke(null, new[] { src }); 
    } 
    public static T CastGeneric<T>(object src) { 
     return (T)Convert.ChangeType(src, typeof(T)); 
    } 
} 
相關問題