繁体   English   中英

C#:如何在 object 期间使用隐式转换运算符进行类型转换?

[英]C#: How can I use implicit cast operator during object to type conversion?

你好!

这是我的情况:我有一些值类型,它使用适当的隐式转换器包装成另一种类型。 如果我将包装类型转换为 object 然后尝试获得原始值,我只能在两步转换中做到这一点。 如果简化我的代码如下:

public enum MyEnum : int
    {
        First,
        Second
    }


    public class Test<T>
    {
        public Test(T val)
        {
            Value = val;
        }

        private T Value { get; set; }


        public static implicit operator T(Test<T> m)
        {
            return m.Value;
        }

        public static implicit operator Test<T>(T m)
        {
            var res = new Test<T>(m);
            return res;
        }
    }


    static void Main()
    {
        object res = new Test<MyEnum>(MyEnum.First);
        Console.WriteLine((MyEnum)(Test<MyEnum>)res);
        Console.WriteLine((MyEnum)res);
    }

首先“Console.WriteLine”工作正常。 第二个失败。

有什么办法可以修改这种行为并让它在没有双重转换的情况下工作?

更新 1

我必须使用 object 来进行值转换(在实际应用中,我必须转换 ComboBox.SelectedItem 属性,并且我不想在 ComboBox 中添加额外的属性,因为我必须在任何地方更改我的 UI 交互代码)。

更新 2

不允许与 System.Object 进行隐式转换。

更新 3

更新了我的示例代码以反映整个问题。

不要那样使用object 像这样写你的第一行:

Test res = new Test(1);

如果您必须首先将它放在 object 中,请记住,此时编译器所知道的只是它是 object,仅此而已。 作为程序员,你有更多关于你期望这个 object 是什么的信息,但是为了让编译器利用这些信息,你必须把它放在你的代码中的某个地方。

更新:
我很高兴我能再次找到这个,因为 Eric Lippert 的这篇几乎非常及时的文章,他从事 C# 语言设计,今天早上起来并深入解释了这个问题:
http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx

如果你想简化转换而不关心性能效果,那么创建扩展方法。

public static T To<T>(this object obj) {
    Type type = obj.GetType();
    MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Static);
    MethodInfo method = methods.FirstOrDefault(mi => (mi.Name == "op_Implicit" || mi.Name == "op_Explicit") && mi.ReturnType == typeof(T));
    if (method == null)
        throw new ArgumentException();
    return (T)method.Invoke(null, new[] { obj });
}

用法

Console.WriteLine(res.To<MyEnum>());

考虑实现IConvertible ,而不是添加隐式运算符。 只需要实现 ToInt32 方法,其他没有意义,可以在其他方法中抛出 InvalidCastException。

之后,您可以使用Convert.ToInt32()方法一步转换您的 object。

甚至

var res = new Test(1);

您的局部变量 res 始终是 object 类型; 所以不起作用的行是试图将不是 int 的 object 转换为无法完成的 int。 与此失败相同:

        object d = 5.5d;
        Console.WriteLine((int)d);

编辑:

也许可能有帮助的模式是这样的:

        if (res.GetType() == typeof(Test))
        {
            Console.WriteLine((int)(Test)res);
        }
        else
        {
            Console.WriteLine((int)res);
        }

这是针对您的问题的非常本地化的解决方案,但也许它对您有用。

虽然错误是由于 res 的类型为 object,但我会让 Test->int 运算符显式...

暂无
暂无

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

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