简体   繁体   中英

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.

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

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.

In my getter, I have a couple separate checks to see if the entire debug system is enabled. 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. The method "GetDefaultValue" accommodates for that, and it returns an object that could be a string, int, bool, anything.

I'm already doing funky reflection stuff to access the MethodInfo, PropertyInfo, etc of the getter and property SerializeAll. I just can't figure out how to not have to also specify the (bool) cast on the return. Again, the goal is as little human editing as possible.

Thank you!

You should be able to do this with a cast to dynamic .

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

Bear in mind that the compiler isn't actually making this into a cast to 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.

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.

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. 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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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