简体   繁体   English

在运行时转换为任意非泛型返回类型,C#

[英]Casting to arbitrary non-generic return type at runtime, C#

I'm trying to make a user-friendly debug framework where users can create more debug variables as easily as possible.我正在尝试制作一个用户友好的调试框架,用户可以在其中尽可能轻松地创建更多调试变量。

I need to cast an object to the return type of my property/method (bool, int, whatever), without knowing what that return type is.我需要将一个对象转换为我的属性/方法的返回类型(bool、int 等),而不知道该返回类型是什么。

tldr: How can I return a non-generic type (in this example bool) from tldr:如何从

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

WITHOUT specifying "return (bool)"?没有指定“返回(布尔)”? So something like所以像

return (GenericThingHereThatPassesAsBool)obj;

or或者

return obj as MyGetSetPropertyReturnType;

---------- ----------

Detail:细节:

I want users to be able to create new properties in this class as easily as possible - basically copying+pasting the whole code block below, and only replacing "SerializeAll" with their variable name, and the type declaration "bool" with the type they want on the field/property declarations.我希望用户能够尽可能轻松地在这个类中创建新属性 - 基本上是复制+粘贴下面的整个代码块,只用他们的变量名替换“SerializeAll”,用他们的类型替换类型声明“bool”想要在字段/属性声明上。

In my getter, I have a couple separate checks to see if the entire debug system is enabled.在我的 getter 中,我有几个单独的检查来查看是否启用了整个调试系统。 If not, it returns a default value for the given variable.如果不是,则返回给定变量的默认值。

[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; }

}

The thing is, I can't return "default" because the default value can be overridden - see the "DebugDefault" attribute where the "default" value for this bool is actually "true", at least as far as my debug system is concerned.问题是,我无法返回“default”,因为可以覆盖默认值 - 请参阅“DebugDefault”属性,其中此 bool 的“default”值实际上是“true”,至少就我的调试系统而言担心的。 The method "GetDefaultValue" accommodates for that, and it returns an object that could be a string, int, bool, anything.方法“GetDefaultValue”适应这种情况,它返回一个对象,可以是字符串、整数、布尔值等。

I'm already doing funky reflection stuff to access the MethodInfo, PropertyInfo, etc of the getter and property SerializeAll.我已经在做一些时髦的反射来访问 getter 和属性 SerializeAll 的 MethodInfo、PropertyInfo 等。 I just can't figure out how to not have to also specify the (bool) cast on the return.我只是不知道如何不必在返回时也指定 (bool) 类型转换。 Again, the goal is as little human editing as possible.同样,目标是尽可能少地进行人工编辑。

Thank you!谢谢!

You should be able to do this with a cast to dynamic .您应该能够通过强制转换为dynamic来做到这一点。

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

Bear in mind that the compiler isn't actually making this into a cast to bool .请记住,编译器实际上并没有将其转换为bool Rather, this makes the compiler ignore compile-time type-safety, and instead the program will use reflection at runtime to figure out the best way to take the value returned from GetDefaultValue and turn it into what it needs to be.相反,这会使编译器忽略编译时类型安全,而是程序将在运行时使用反射来找出获取从 GetDefaultValue 返回的值并将其转换为所需值的最佳方法。

I want users to be able to create new properties in this class as easily as possible...我希望用户能够尽可能轻松地在此类中创建新属性...

This is a good principle.这是一个很好的原则。

... basically copying+pasting the whole code block below, and only replacing "SerializeAll" with their variable name, and the type declaration "bool" with the type they want on the field/property declarations. ...基本上是复制+粘贴下面的整个代码块,只用他们的变量名替换“SerializeAll”,用他们想要的字段/属性声明的类型替换类型声明“bool”。

That totally breaks the principle you just mentioned, and results in a bunch of boilerplate code and other code smells.这完全打破了你刚才提到的原则,并导致一堆样板代码和其他代码异味。

In theory, you could probably create a Fody Weaver or something to add this boilerplate code upon compilation.从理论上讲,您可能可以创建一个 Fody Weaver 或其他东西来在编译时添加此样板代码。 But that's probably more work than it's worth.但这可能比它的价值更多。

I would hazard a guess that this is an "XY Problem", where you're asking how to achieve the solution that you've imagined, rather than asking how to solve the problem you're actually facing.我冒昧地猜测这是一个“XY 问题”,你问的是如何实现你想象的解决方案,而不是问如何解决你实际面临的问题。

Why should every property in your class return a completely different value if certain private fields are set a certain way?如果某些私有字段以某种方式设置,为什么类中的每个属性都应该返回完全不同的值? This sounds like a big Separation of Concerns problem, where you're tasking your class with doing two completely different things.这听起来像是一个很大的关注点分离问题,你要让你的班级做两件完全不同的事情。 I strongly suggest you find another way to solve the problem you're trying to solve.我强烈建议您找到另一种方法来解决您正在尝试解决的问题。 For example, when code tries to get an instance of your class, it could go through a method that checks the classEnabled and debug.debugEnabled concepts (which probably belong in a different class), and returns an instance with the properties all set to their defaults.例如,当代码尝试获取您的类的实例时,它可以通过检查classEnableddebug.debugEnabled概念(可能属于不同的类)的方法,并返回一个实例,其属性都设置为它们的默认值。

Please Link click here -> How to cast Object to boolean?请点击此处链接 -> 如何将对象转换为布尔值?

or或者

I think you need to study for Generic class我认为你需要学习通用课程

Check if a class is derived from a generic class 检查类是否派生自泛型类

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM