简体   繁体   English

C#:自定义隐式转换运算符失败

[英]C# : Custom implicit cast operator failing

Alright, I've been trying to find any information on this for a while. 好吧,我一直试图找到有关这方面的任何信息。 I built a small class to see how hard type-safe-enums are to implement for strings, because I want to use them for database field-names and such. 我构建了一个小类来查看为字符串实现类型安全枚举的难度,因为我想将它们用于数据库字段名等。 I've never liked the fact that enums could only be used for integers. 我从来不喜欢枚举只能用于整数的事实。
However, even though I have implemented an implicit operator for this class, every time I try to use it, it gives me an invalid cast exception. 但是,即使我已经为这个类实现了一个implicit operator ,每次我尝试使用它时,它都会给我一个无效的强制转换异常。 I'm at a loss, as I can see nothing wrong with my code at this point. 我很茫然,因为在这一点上我的代码没有任何问题。
Here's the class: 这是班级:

/// <summary>
/// SBool - type-safe-enum for boolean strings
/// </summary>
public sealed class SBool
{

    private readonly String name;
    private readonly int value;

    // these guys were for conversions. They might work better in another case,
    //  but for this one, they weren't very helpful.
    // ((I.e. they didn't work either.))
    //private static readonly Dictionary<SBool, String> stringsByBool = new Dictionary<SBool, String>();
    //private static readonly Dictionary<String, SBool> boolsByString = new Dictionary<String, SBool>();

    public static readonly SBool True = new SBool( 1, "true" );
    public static readonly SBool False = new SBool( 0, "false" );

    private SBool( int value, String name )
    {
        this.name = name;
        this.value = value;
        //stringsByBool[this] = name;
        //boolsByString[name] = this;
    }

    private SBool( SBool sbool )
    {
        this.name = sbool.name;
        this.value = sbool.value;
        //stringsByBool[this] = name;
        //boolsByString[name] = this;
    }

    public override String ToString()
    {
        return name;
    }

    /// <summary>
    /// allows implicit casting of SBools to strings
    /// </summary>
    /// <param name="sbool">the SBool to cast into a string</param>
    /// <returns>the string equivalent of the SBool (its value)</returns>
    public static implicit operator String( SBool sbool )
    {
        if ( sbool == SBool.True )
            return SBool.True.name;
        else
            return SBool.False.name;
    }

    /// <summary>
    /// implicitly cast a string into a SBool.
    /// </summary>
    /// <param name="str">the string to attempt to cast as a SBool</param>
    /// <returns>the SBool equivalent of the string,
    /// SBool.False if not either "true" or "false".</returns>
    public static explicit operator SBool( String str )
    {
        if ( !String.IsNullOrEmpty(str) && str.ToLower() == "true" )
            return SBool.True;
        else
            return SBool.False;
    }

    public static bool operator ==( SBool left, SBool right )
    {
        return left.value == right.value;
    }

    public static bool operator !=( SBool left, SBool right )
    {
        return left.value != right.value;
    }
}


This is failing on the check of a Session variable: 这在检查Session变量时失败了:
if( ( (string)Session["variable"] ) == SBool.False ) with an InvalidCastException, if( ( (string)Session["variable"] ) == SBool.False )带有InvalidCastException,
and I quite frankly have no idea why. 我坦率地不明白为什么。

Thanks in advance; 提前致谢; cookies for anyone who can explain why this doesn't work (cookies not available in all areas). 任何人都可以解释为什么这不起作用的cookie(饼干不是在所有领域都可用)。 I'm going to get other things fixed, but let me know if there's anything that is unclear. 我将修复其他问题,但如果有任何不清楚的地方,请告诉我。 For more info on Type-Safe enums, here's one of the SO posts I based this class off of. 有关Type-Safe枚举的更多信息,这是我基于此课程的SO帖子之一。

[MetaEDIT] disregard this. [MetaEDIT]无视这一点。 I was horribly, horribly mistaken. 我非常可怕,非常错误。 [/edit] [/编辑]

User defined implicit and explicit operators are entirely a compile time mechanism, not a runtime mechanism. 用户定义的隐式和显式运算符完全是编译时机制,而不是运行时机制。 Once the code is compiled the runtime has no idea about any user defined conversion operators. 编译代码后,运行时不知道任何用户定义的转换运算符。

When the compiler is doing it's type checking and sees that a Foo is expected but the actual value is a Bar it will first check through the built in language implicit conversion operators to see if an appropriate conversion exists. 当编译器进行类型检查并看到Foo是预期的但实际值是Bar ,它将首先检查内置语言隐式转换运算符,以查看是否存在适当的转换。 If it doesn't, it checks through the definition of both Foo and Bar for implicit conversion operators, if it finds one it will add in a call to the relevant static method to perform the conversion. 如果没有,它会检查隐式转换运算符的FooBar的定义,如果它找到一个它将添加到相关静态方法的调用中以执行转换。 Once you get to runtime only the built in language implicit operators will be applied. 一旦进入运行时,将仅应用内置语言隐式运算符。

In this case you aren't converting from SBool to a string , you're converting from object to string (as far as the compiler is concerned) and there is no conversion operator to handle that. 在这种情况下,您不是从SBool转换为string ,而是从object转换为string (就编译器而言)并且没有转换运算符来处理它。

You need to first cast the result of the Session variable to SBool (which is what it really is) and then to some other type in order to be able to leverage the user defined conversion operators. 您需要首先将Session变量的结果转换为SBool (实际上是它),然后转换为其他类型,以便能够利用用户定义的转换运算符。 So: 所以:

if( ( (SBool)Session["variable"] ) == SBool.False )

will work just fine. 会工作得很好。

As Servy mentioned these types of cast happen at compile time. 正如Servy所说,这些类型的演员阵容发生在编译时。 However there is a way to force this check to occur at runtime by using dynamic keyword. 但是,有一种方法可以通过使用动态关键字在运行时强制执行此检查。 Instead of casting to SBool cast to dynamic. 而不是将SBool强制转换为动态。 This will cause cast operators to be executed at run time. 这将导致在运行时执行强制转换操作符。

In my opinion casting to SBool is a cleaner and less error prone solution. 在我看来,转向SBool是一种更清晰且不易出错的解决方案。

Wen you're casting Session[] to a string, you're performing an explicit conversion. 你正在将Session []转换为字符串,你正在进行显式转换。 You don't have a SBool->String explicit operator defined, only implicit. 您没有定义SBool-> String显式运算符,只是隐式运算符。

You need to add an explicit SBool->string conversion. 您需要添加显式的SBool->字符串转换。

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

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