请注意,我的逻辑是复杂的,我已经简化了一切,专注于这个问题。
我有函数字典,我必须调用它,但是函数将类型T作为输入参数,它是派生类型,我没有访问权限,它可以是运行时的任何东西。我该如何调用它?
我收到以下错误,
Unable to cast object of type
'System.Func`2[DerivedClass,System.String]' to type
'System.Func`2[BaseClass,System.String]'.
我尝试过的替代品,我已经知道了,我正在寻找更好的性能,然后是以下替代方案。
两种选择都非常昂贵,我需要更简单的方法。
这不是我为什么会遇到这个编译器错误的问题,或者我是否需要重新设计我的应用程序,当我已经说过我有两个调用Func的替代方案时,我正在寻找第三个更简单的替代方案,如果存在< /强>
如何在无法访问DerivedClass的情况下调用Func<DerivedClass,String>
?我和我有一个对象。
class Program
{
static void Main(string[] args)
{
object input = new DerivedClass();
Func<BaseClass, string> f = null;
Func<DerivedClass, string> a = s => s.ToString();
object obj = a;
// ERROR
f = (Func<BaseClass, string>)obj;
Console.WriteLine(f(input));
Console.ReadLine();
}
}
public class BaseClass {
public override string ToString()
{
return "Base Class";
}
}
public class DerivedClass : BaseClass {
public override string ToString()
{
return "Derived Class";
}
}
答案 0 :(得分:3)
你在这里尝试做的事情并没有多大意义。假设你有一个A类,以及两个继承它的B和C类。
如果你能够做你在这里说的话,那么使用函数Func<B, string>
并将其转换为Func<A, string>
意味着你得到的函数也可以将C的实例作为参数因为C也继承自A。
事实上,你可以更进一步说,因为所有东西都是从object继承的,你可以将任何函数转换为Func<object, string>
,然后传入你想要的任何参数作为参数。
答案 1 :(得分:2)
让我们摆脱代表一秒钟,并根据他们抽象的方法来考虑这一点。请考虑以下Foo
方法:
public static void Foo(int i)
{
Console.WriteLine(i + 2);
}
现在我们有了另一种方法Bar
。它接受object
。我们想在参数上调用Foo
。
public static void Bar(object o)
{
Foo(o);
}
当然,这不会奏效。我们无法知道提供的对象实际上是int
。
这通常意味着两件事之一:
你实际上并不想这样做;你无法知道更通用的参数实际上是一个正确的更多派生参数的实例;你应该重新设计你的申请。
您知道编译器没有的东西,虽然编译器无法验证此约束是否正确,但实际上它在运行时无论出于何种原因都是有效的。由于您知道它不会失败,您可以使用强制转换通知编译器,并将类型检查推迟到运行时。
如果你碰巧在这里的第二个位置而不是第一个位置,你可以不通过强制转换委托来添加强制转换,而是通过创建一个新的方法(可能通过lambda)来对参数执行强制转换然后调用另一个代理:
Func<DerivedClass, string> derivedSelector = derived => derived.ToString();
Func<BaseClass, string> baseSelector = s => derivedSelector((DerivedClass)s);