C# 是否可以将变量转换为存储在另一个变量中的类型?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/464765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is possible to cast a variable to a type stored in another variable?
提问by Marek Grzenkowicz
This is what I need to do:
这是我需要做的:
object foo = GetFoo();
Type t = typeof(BarType);
(foo as t).FunctionThatExistsInBarType();
Can something like this be done?
可以做这样的事情吗?
采纳答案by Quassnoi
No, you cannot. C# does not implement duck typing.
你不能。C# 没有实现鸭子类型。
You must implement an interface and cast to it.
您必须实现一个接口并转换为它。
(However there are attempts to do it. Look at Duck Typing Projectfor an example.)
(但是有人尝试这样做。以Duck Typing Project为例。)
回答by GvS
You can use the Convert.ChangeTypemethod.
您可以使用Convert.ChangeType方法。
object foo = GetFoo();
Type t = typeof(string);
string bar = (string)Convert.ChangeType(foo, t);
回答by ShuggyCoUk
Your original question was flawed in that you ask to treat a variable as a type which is not known at compile time but note that you have string defined on the left hand side when you declare your variable. C# as of 3.5 is statically typed.
您最初的问题有缺陷,因为您要求将变量视为在编译时未知的类型,但请注意,当您声明变量时,在左侧定义了字符串。从 3.5 开始,C# 是静态类型的。
Once dynamic is available you could do something like this:
一旦动态可用,您可以执行以下操作:
dynamic foo = GetFoo();
foo.FunctionThatExistsInBarType();
For when you don't know what the type is but you know it will always support the instance method FunctionThatExistsInBarType();
因为当你不知道类型是什么但你知道它总是支持实例方法 FunctionThatExistsInBarType();
for now you are forced to use reflection (or code gen which really amounts to much the same thing but more expensive up front and faster later).
现在你被迫使用反射(或代码生成,它实际上相当于相同的东西,但前期成本更高,后期更快)。
// 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);
回答by Marcus Hansson
Provided you know all required types at compile-time, duck typingis (sort of) possible:
如果您在编译时知道所有必需的类型,那么鸭子类型是(有点)可能的:
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)"; }
}
Output:
输出:
Dostuff(Foo foo)
Dostuff(Bar bar);
DoStuff(object fb);
If you end up implementing a lot of methods that basically do exactly the same, consider implementing an interface.
如果你最终实现了很多基本相同的方法,考虑实现一个接口。
回答by rmrfhome
Since dynamics were added to c#, I think we can do it in this way:
由于在c#中加入了dynamics,我觉得我们可以这样做:
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));
}
}