繁体   English   中英

如何在 C# 中使用带有 Generics 的重载运算符?

[英]How does one use overloaded operators with Generics in C#?

我正在尝试编写一个 class 来存储、处理、保存和加载数据。 我希望当我最终完成它时,它将简化并主要自动化组织大量字段的过程,将它们保存到文件中,然后从这些文件中检索它们。

我的第一个想法是使用动态,但我不喜欢一个动态的性能下降,而原始形式的 class 有很多动态。 我想我会消除所有这些,只使用 generics,这确实让事情变得更顺畅了。 它还减少了所需代码的数量。 但是,我遇到了一个新问题。 我正在尝试重载运算符以使值的操作更容易一些。

它是这样设置的:

public class DataElement<T>
{

        public T In;
        public T Out;

}

这是一个极其简化和淡化的版本,但对于我目前正在努力解决的问题已经足够了。 这是问题所在:

        public static DataElement<T> operator +(DataElement<T> d, T val)
        {
            object o = val;
            object oo = d.Out;
            if (typeof(T) == typeof(string))
            {
                string s = o.ToString();
                s += oo.ToString();
                oo = s;
            }
            else
            {
                if (typeof(T) == typeof(int))
                {
                    int i = int.Parse(o.ToString());
                    i += int.Parse(oo.ToString());
                    oo = i;
                }
                else if (typeof(T) == typeof(float))
                {
                    float f = float.Parse(o.ToString());
                    f += float.Parse(oo.ToString());
                    oo = f;
                }
                else if (typeof(T) == typeof(long))
                {
                    long l = long.Parse(o.ToString());
                    l += long.Parse(oo.ToString());
                    oo = l;
                }
                else if (typeof(T) == typeof(char))
                {

                }
            }
            d.Out = (T)oo;
            return d;
        }

我什至不确定这是否会奏效。 我还没有测试过。 主要是因为不喜欢。 所有这些 IF 语句。 它又丑又笨重。 理想的解决方案是使用 SWITCH 语句,但哦不。 VS 告诉我,类型的 SWITCH 语句仅在 C# 的绝对最新版本中受支持。 而且我想不出任何其他方法来做到这一点。 如果我直接尝试,像这样:

    d.Out += val;

VS 告诉我“运算符 '+=' 不能应用于 'T' 和 'T' 类型的操作数” 好的,然后。 如何完成我想做的事情? 当我将“val”设置为“int”而不是通用“T”时,它告诉我同样的事情。 有什么我想念的吗? 我在这里重新发明轮子吗?

如果您坚持使用旧版本,您可以像这样将 T 转换为 TOther: (TOther)(object)o

if (typeof(T) == typeof(int)) {
    int i = (int)(object)o;
    ...

这个问题的真正解决方案是使用泛型约束将T限制为支持加法的类型。 不幸的是,整型数字类型没有通用接口,但有一些线程有很长的解决方法列表

我的建议是将问题委托给调用者,即

public DataElement<T> Add(T val, Func<T, T, T> addMethod){
       return new DataElement<T>{In = this.In, Out = addMethod(this.Out, val)};
}

请注意,这使用常规方法而不是运算符,因为运算符必须满足某些特定规则。 我也会非常小心地改变输入对象,我通常希望像“add”这样的基本方法返回一个新的 object,而不是修改输入对象。

但是,如果目标是

编写一个 class 用于存储、处理、保存和加载数据

然后我建议使用序列化库,至少对于“存储、保存和加载”部分。 因为这些是为了将对象转换为可以保存到磁盘或通过网络发送等的序列化形式。Json.Net是一种流行的替代方案,但还有许多其他替代方案。

暂无
暂无

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

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