有人可以帮助我了解为什么以下内容不起作用吗?
void test(int i)
{
Console.WriteLine("int");
}
void test(String s)
{
Console.WriteLine("String");
}
void runMe()
{
object obj = 1;
Type t = typeof(int);
test((t)obj);
}
您收到“找不到类型或名称空间名称't'”错误。
有没有办法使这项工作有效?我需要将对象转换为仅在运行时才知道的特定类型,但是我发现的所有选项只是在转换数据,但仍将其存储在对象中。
编辑:添加了一些伪方法以提供更多上下文。
答案 0 :(得分:2)
看起来您基本上是在尝试执行动态调度。您尝试使用的方式将无法正常工作,因为在使用静态类型时,所有重载解析都是在执行时执行的。
但是,您可以使用dynamic
类型的动态类型来代替。此时,将在执行时执行重载解析:
void Test(int i)
{
Console.WriteLine("int");
}
void Test(String s)
{
Console.WriteLine("String");
}
void RunMe()
{
dynamic obj = 1;
// The right overload is picked at execution time
Test(obj);
}
这将完成您在问题中显示的内容-但这不一定是最好的方法。如果您可以可能坚持使用静态类型(不使用反射),那么我会这样做。如果您只能处理一组已知的类型,则可能需要保留Dictionary<Type, Action<object>>
或类似的内容……尽管随后您需要考虑一些麻烦的事情,例如子类型化等。
如果您要做使用动态类型,我将尝试仅将其用于一小段代码。只要您可以“退出”动态类型,就可以这样做(例如,将动态绑定调用的结果强制转换为其预期的返回类型)。
答案 1 :(得分:0)
这是一个示例,其中有几种方法可以将其组合为一个示例。
第一种方法是重载您的方法以获取受支持的类型(当在编译时知道类型时可以直接调用这些方法),并创建一个具有对象类型参数的通用默认重载方法,该方法在内部检查受支持的类型和调用适当的特定于类型的方法(仅适用于运行时已知的类型)。
第二种方法可以用作第一种方法的扩展,但是您也可以仅实现第二种方法而跳过第一部分。由于您知道运行时开始时的类型,并且预计该类型不会随每次调用更改,因此您可以跳过每次调用的类型检查,而是在加载配置时进行一次检查,然后设置适当的值委托。
尝试:https://dotnetfiddle.net/06JYE1#
using System;
public class Program
{
public static void Main()
{
var p = new Program();
object s = "Hi";
object i = 42;
object f = 3.14;
p.Test(s);
p.Test(i);
p.Test(f);
p.SetTestType(GetConfigType());
p.ConfiguredTest("Hello");
p.ConfiguredTest(s);
}
public static Type GetConfigType() { return typeof(string); }
Action<object> ConfiguredTest;
void SetTestType(Type type)
{
if (type == typeof(string))
ConfiguredTest = o => Test((string)o);
else if (type == typeof(int))
ConfiguredTest = o => Test((int)o);
else
ConfiguredTest = null;
}
void Test(object o) // catch-all when type is not known until runtime
{
if (ConfiguredTest != null)
{
ConfiguredTest(o); // if type is configured, we can skip type checking
}
else // if type is not configured, check for supported types
{
if (o is string)
Test((string)o);
else if (o is int)
Test((int)o);
else
Console.WriteLine("Unsupported type: " + o.GetType());
}
}
void Test(int i) { Console.WriteLine("Int = " + i); }
void Test(String s) { Console.WriteLine("String = " + s); }
}