首页 > 解决方案 > 在运行时强制转换为任意非泛型返回类型,C#

问题描述

我正在尝试制作一个用户友好的调试框架,用户可以在其中尽可能轻松地创建更多调试变量。

我需要将一个对象转换为我的属性/方法的返回类型(bool、int 等),而不知道该返回类型是什么。

tldr:如何从

public bool MyGetSetProperty {
    get {
        object obj = new object();
        return (bool)obj;
    }
}

没有指定“返回(布尔)”?所以像

return (GenericThingHereThatPassesAsBool)obj;

或者

return obj as MyGetSetPropertyReturnType;

----------

细节:

我希望用户能够尽可能轻松地在此类中创建新属性-基本上是复制+粘贴下面的整个代码块,并且仅将“SerializeAll”替换为其变量名,并将类型声明“bool”替换为他们的类型想要在字段/属性声明上。

在我的吸气剂中,我有几个单独的检查来查看是否启用了整个调试系统。如果不是,它返回给定变量的默认值。

[Tooltip ("Serialize ALL XML output fields?"), SerializeField]
private bool debugSerializeAll = false;

/// <summary>
/// Serialize ALL XML output fields?
/// </summary>
[DebugValue, DebugDefault (true)]
public bool SerializeAll {

    get {
        if (!classEnabled || !debug.debugEnabled)
            return (bool)GetDefaultValue (MethodBase.GetCurrentMethod ());
        return debugSerializeAll;
    }

    set { debugSerializeAll = value; }

}

问题是,我不能返回“默认”,因为可以覆盖默认值 - 请参阅“DebugDefault”属性,其中该布尔的“默认”值实际上是“真”,至少就我的调试系统而言是担心的。方法“GetDefaultValue”适应了这一点,它返回一个可以是字符串、int、bool 或任何东西的对象。

我已经在做一些时髦的反射来访问 getter 和属性 SerializeAll 的 MethodInfo、PropertyInfo 等。我只是不知道如何不必在返回时指定 (bool) 强制转换。同样,目标是尽可能少的人工编辑。

谢谢!

标签: c#genericsreflectioncastingreturn-type

解决方案


你应该可以通过强制转换来做到这一点dynamic

        return (dynamic)GetDefaultValue (MethodBase.GetCurrentMethod ());

请记住,编译器实际上并没有将其转换为bool. 相反,这会使编译器忽略编译时类型安全,而是程序将在运行时使用反射来找出获取从 GetDefaultValue 返回的值并将其转换为所需值的最佳方法。

我希望用户能够尽可能轻松地在此类中创建新属性...

这是一个很好的原则。

...基本上复制+粘贴下面的整个代码块,并且仅将“SerializeAll”替换为其变量名,并将类型声明“bool”替换为他们在字段/属性声明中想要的类型。

这完全违反了您刚才提到的原则,并导致一堆样板代码和其他代码异味。

理论上,您可能可以创建一个 Fody Weaver 或其他东西来在编译时添加此样板代码。但这可能比它的价值更多。

我会冒险猜测这是一个“XY 问题”,您在问如何实现您想象的解决方案,而不是问如何解决您实际面临的问题。

如果某些私有字段以某种方式设置,为什么你的类中的每个属性都应该返回一个完全不同的值?这听起来像是一个很大的关注点分离问题,你要让你的班级做两件完全不同的事情。我强烈建议您找到另一种方法来解决您要解决的问题。例如,当代码试图获取您的类的实例时,它可能会通过一个方法来检查classEnableddebug.debugEnabled概念(它们可能属于不同的类),并返回一个属性全部设置为默认值的实例。


推荐阅读