RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / user-201200

Artem's questions

Martin Hope
Artem
Asked: 2024-06-28 17:45:57 +0000 UTC

字符串插值的陷阱

  • 6

考虑这一行:

"{0} Client called server Method: {1}) Returned: {2} Status: {3}.", 
                    session.GetClientInfo(), request, response, status

$"{session.GetClientInfo()} Client called server Method: {request}) Returned: {response} Status: {status}."

事实证明,请求、响应、状态可能包含一对(或者甚至可能是一对,我没有检查过)花括号。在这种情况下,再次重新格式化可能会导致错误。

什么时候会发生这种情况?例如,如果我们有一个这样的函数:

static void outMessage(LogFilter type, LogLevel level, string text, params object[] args)
{
    Logger logger = GetLoggerByType(type);
    logger.write(new LogMessage(level, type, string.Format(text, args)));
}

如果参数是带有大括号的字符串,其中包含格式无法识别的表达式,例如: 在此输入图像描述

{{ "useBindlessRpc": true, "meteringLevel": "METERING_LEVEL_LEGACY", "clientSdkInfo": { "sdkName": "BGS C++ SDK", "sdkVersion": { "majorVersion": 6, "minorVersion": 2, "patchVersion": 0, "versionString": "6.2.0" }, "protocolVersion": { "majorVersion": 3, "minorVersion": 11, "patchVersion": 10, "versionString": "3.11.10-44dad063b5" } } }}

然后你可能会收到一个错误: 在此输入图像描述

为什么会有这样的函数存在:

  1. 可能是在引入插值之前创建的
  2. 支持这两个选项
  3. 也许它是为了支持组合选项(这不是一个好主意,因为在这种情况下无法避免错误)

变量中的花括号来自哪里:

  1. 键盘输入
  2. 序列化结果
  3. 从任何其他地方

如果里面有括号, 也可能会出现这个问题:Prior to C# 10, if an interpolated string has the type string, it's typically transformed into a String.Format method call. The compiler may replace String.Format with String.Concat if the analyzed behavior would be equivalent to concatenation.

转义括号有帮助吗? - 我没试过,但 C# 代码禁止转义它们

问: 这种情况该怎么办?

UPD: 在这个平台上,也在这台机器上,不会发生错误。可以假设这个错误取决于“天知道是什么”。我假设它取决于编码。根据错误消息,需要 ASCII,尽管默认值似乎是 UTF16。为什么需要这种编码——我不知道。也许这根本不是一个正确的错误。厌倦了戳调试器。大家有兴趣的话可以自己挖一下。

在此输入图像描述

c#
  • 2 个回答
  • 65 Views
Martin Hope
Artem
Asked: 2024-05-26 14:57:56 +0000 UTC

您应该创建包装类型吗?在 C# 中提高代码可读性?(输入 1 个字段)

  • 9

C# 因在类型方面比 C++ 更严格而闻名。然而,我注意到没有人特别急于创建包装类型以提高可读性和易于转换。

例如,我正在编写代码,其中时间有时以秒为单位,有时以毫秒为单位,并且是恒定的,并且在可能的情况下,所有转换都是手动执行并乘以 1000。

我尝试创建两个类型为秒和毫秒的只读记录结构,从而重载转换运算符。我什至在其中包含了最大值的检查。

但我再次开始怀疑自己是否正确地花了两周的时间来完成这一切……为什么没有人这样做。我无法回答这个问题,但以下想法悄然浮现:

  • 程序速度下降
  • int/uint/long 的持续问题,我总是想节省空间并不断使用 int/uint/long 以确保它适合或使用负数
  • 转换运算符的问题(我最近发现它们在 Sharp 中向后工作,并且我尝试解决这个问题的任何尝试都归结为每个人都写这是一个错误或一个功能这一事实。尽管我没有看到这有任何意义完全没有(实际上是这样的)
  • 每个人都只是编写程序并最初使用 DateTime/TimeSpan - 然而,有时在几秒钟内为一个变量分配 8 个字节仍然是大胆的,特别是当一个类中有很多这样的变量并且经常使用时

一般来说,请分享您的经验。也许如果我从头开始编写程序,我就不会打扰。我遇到过由不同的人编写的项目 + 使用多个库,而这些库又具有自己的数据存储类型。有这样的油醋汁,我就坐下来,以为我会把所有的东西都清理干净。现在我越来越被怀疑所淹没,我简直陷入了恍惚之中:“我应该继续花时间在这上面,还是退缩而不受苦?”

public readonly record struct Seconds
{
    public readonly int Ticks;
    public readonly static Seconds MaxValue = new Seconds(int.MaxValue);
    public readonly static Seconds MinValue = new Seconds(int.MinValue);
    public readonly static Seconds Zero = new Seconds(0);

    public Seconds(int ticks)
    {
        Ticks = ticks;
    }

    public static implicit operator int(Seconds time)
    {
        return time.Ticks;
    }

    public static explicit operator Seconds(int ticks)
    {
        return new Seconds(ticks);
    }

    public static implicit operator float(Seconds time)
    {
        return time.Ticks;
    }

    public static implicit operator TimeSpan(Seconds time)
    {
        return TimeSpan.FromSeconds(time.Ticks);
    }

    public static explicit operator Seconds(TimeSpan span)
    {
        var ticks = span.TotalSeconds;
        if (ticks < int.MinValue || ticks > int.MaxValue)
            throw new Exception("explicit operator Seconds(TimeSpan) : out of range value");
        return new((int)ticks);
    }

    public static explicit operator Seconds(Milliseconds time)
    {
        return new(time.Ticks / 1000);
    }

    public static explicit operator Seconds(RelativeTime span)
    {
        return new((int)(span.Milliseconds / 1000));
    }

    public static Seconds operator -(Seconds right)
    {
        return (Seconds)(-right.Ticks);
    }

    public static Seconds operator -(Seconds left, Seconds right)
    {
        return (Seconds)(left.Ticks - right.Ticks);
    }

    public static Seconds operator +(Seconds left, Seconds right)
    {
        return (Seconds)(left.Ticks + right.Ticks);
    }

    public static Seconds operator *(Seconds left, Seconds right)
    {
        return (Seconds)(left.Ticks * right.Ticks);
    }

    public static float operator /(Seconds left, Seconds right)
    {
        return (float)left.Ticks / right.Ticks;
    }

    public static Seconds operator %(Seconds left, Seconds right)
    {
        return (Seconds)(left.Ticks % right.Ticks);
    }

    public static bool operator >(Seconds left, Seconds right)
    {
        return left.Ticks > right.Ticks;
    }

    public static bool operator <(Seconds left, Seconds right)
    {
        return left.Ticks < right.Ticks;
    }

    public static bool operator >=(Seconds left, Seconds right)
    {
        return left.Ticks >= right.Ticks;
    }

    public static bool operator <=(Seconds left, Seconds right)
    {
        return left.Ticks <= right.Ticks;
    }

    public override string ToString()
    {
        return Ticks.ToString();
    }

    public static bool TryParse(string s, out Seconds result)
    {        
        bool isSuccessful = int.TryParse(s, out int parsed);
        result = (Seconds)parsed;
        return isSuccessful;
    }
}


public readonly record struct Milliseconds
{
    public readonly int Ticks;
    public readonly static Milliseconds MaxValue = new Milliseconds(int.MaxValue);
    public readonly static Milliseconds MinValue = new Milliseconds(int.MinValue);
    public readonly static Milliseconds Zero = new Milliseconds(0);

    public Milliseconds(int ticks)
    {
        Ticks = ticks;
    }

    public static implicit operator int(Milliseconds time)
    {
        return time.Ticks;
    }

    public static explicit operator Milliseconds(int ticks)
    {
        return new Milliseconds(ticks);
    }

    public static implicit operator float(Milliseconds time)
    {
        return time.Ticks;
    }

    public static implicit operator TimeSpan(Milliseconds time)
    {
        return TimeSpan.FromMilliseconds(time.Ticks);
    }

    public static explicit operator Milliseconds(TimeSpan span)
    {
        var ticks = span.TotalMilliseconds;
        if (ticks > int.MaxValue || ticks < int.MinValue)
            throw new Exception("explicit operator Milliseconds(TimeSpan) : out of range value");
        return new((int)ticks);
    }

    public static explicit operator Milliseconds(Seconds time)
    {
        var ticks = (long)time.Ticks * 1000;
        if (ticks > int.MaxValue || ticks < int.MinValue)
            throw new Exception("explicit operator Milliseconds(Seconds) : out of range value");
        return new Milliseconds((int)ticks);
    }

    public static explicit operator Milliseconds(RelativeTime span)
    {
        var ticks = span.Milliseconds;
        if (ticks > int.MaxValue)
            throw new Exception("explicit operator Milliseconds(RelativeTime) : out of range value");
        return new((int)ticks);
    }

    public static Milliseconds operator -(Milliseconds right)
    {
        return (Milliseconds)(-right.Ticks);
    }

    public static Milliseconds operator -(Milliseconds left, Milliseconds right)
    {
        return (Milliseconds)(left.Ticks - right.Ticks);
    }

    public static Milliseconds operator +(Milliseconds left, Milliseconds right)
    {
        return (Milliseconds)(left.Ticks + right.Ticks);
    }

    public static Milliseconds operator *(Milliseconds left, Milliseconds right)
    {
        return (Milliseconds)(left.Ticks * right.Ticks);
    }

    public static float operator /(Milliseconds left, Milliseconds right)
    {
        return (float)left.Ticks / right.Ticks;
    }

    public static Milliseconds operator %(Milliseconds left, Milliseconds right)
    {
        return (Milliseconds)(left.Ticks % right.Ticks);
    }

    public static bool operator >(Milliseconds left, Milliseconds right)
    {
        return left.Ticks > right.Ticks;
    }

    public static bool operator <(Milliseconds left, Milliseconds right)
    {
        return left.Ticks < right.Ticks;
    }

    public static bool operator >=(Milliseconds left, Milliseconds right)
    {
        return left.Ticks >= right.Ticks;
    }

    public static bool operator <=(Milliseconds left, Milliseconds right)
    {
        return left.Ticks <= right.Ticks;
    }

    public override string ToString()
    {
        return Ticks.ToString();
    }

    public static bool TryParse(string s, out Milliseconds result)
    {
        bool isSuccessful = int.TryParse(s, out int parsed);
        result = (Milliseconds)parsed;
        return isSuccessful;
    }
}

public readonly record struct RelativeTime
{
    public readonly uint Milliseconds;
    public readonly static RelativeTime MaxValue = new RelativeTime(uint.MaxValue);
    public readonly static RelativeTime MinValue = new RelativeTime(uint.MinValue);
    public readonly static RelativeTime Zero = new RelativeTime(0);

    public RelativeTime(uint milliseconds)
    {
        Milliseconds = milliseconds;
    }

    public static implicit operator uint(RelativeTime time)
    {
        return time.Milliseconds;
    }

    public static explicit operator RelativeTime(uint milliseconds)
    {
        return new RelativeTime(milliseconds);
    }    

    public static implicit operator float(RelativeTime time)
    {
        return time.Milliseconds;
    }

    public static RelativeTime operator -(RelativeTime left, RelativeTime right)
    {
        return (RelativeTime)(left.Milliseconds - right.Milliseconds);
    }

    public static RelativeTime operator +(RelativeTime left, RelativeTime right)
    {
        return (RelativeTime)(left.Milliseconds + right.Milliseconds);
    }

    public static RelativeTime operator +(RelativeTime left, Milliseconds right)
    {
        return (RelativeTime)(left.Milliseconds + right.Ticks);
    }

    public static RelativeTime operator -(RelativeTime left, Milliseconds right)
    {
        return (RelativeTime)(left.Milliseconds - right.Ticks);
    }

    public static bool operator >(RelativeTime left, RelativeTime right)
    {
        return left.Milliseconds > right.Milliseconds;
    }

    public static bool operator <(RelativeTime left, RelativeTime right)
    {
        return left.Milliseconds < right.Milliseconds;
    }

    public static bool operator >=(RelativeTime left, RelativeTime right)
    {
        return left.Milliseconds >= right.Milliseconds;
    }

    public static bool operator <=(RelativeTime left, RelativeTime right)
    {
        return left.Milliseconds <= right.Milliseconds;
    }

    public override string ToString()
    {
        return Milliseconds.ToString();
    }

    public static bool TryParse(string s, out RelativeTime result)
    {
        bool isSuccessful = uint.TryParse(s, out uint parsed);
        result = (RelativeTime)parsed;
        return isSuccessful;
    }
}

public readonly record struct UnixTime
{
    public readonly int Seconds;
    public static readonly UnixTime Zero = new UnixTime(0);
    public static readonly UnixTime Infinity = new UnixTime(-1);

    public UnixTime(int ticks)
    {
        if (ticks < 0 && ticks != -1)
            throw new Exception("constructor UnixTime(int) : too low value");
        Seconds = ticks;
    }

    public static implicit operator int(UnixTime time)
    {
        return time.Seconds;
    }

    public static explicit operator UnixTime(int seconds)
    {
        if (seconds < 0 && seconds != -1)
            throw new Exception("explicit operator UnixTime(int) : too low value");
        return new UnixTime(seconds);
    }

    public static explicit operator UnixTime(UnixTime64 time)
    {
        if (time.Seconds > int.MaxValue)
            throw new Exception("explicit operator UnixTime(UnixTime64) : too high value");
        return (UnixTime)(int)time.Seconds;
    }

    public static explicit operator UnixTime(UnixTimeMS time)
    {
        var seconds = time.Milliseconds / 1000;
        if (seconds > int.MaxValue)
            throw new Exception("explicit operator UnixTime(UnixTimeMS) : too high value");
        return (UnixTime)(int)seconds;
    }

    public static explicit operator DateTime(UnixTime time)
    {
        if (time == Infinity)
            return Time.Infinity;

        if (time == 0)
            return Time.Zero;

        return DateTimeOffset.FromUnixTimeSeconds(time).UtcDateTime;
    }

    public static explicit operator UnixTime(DateTime dateTime)
    {
        if (dateTime == Time.Infinity)
            return Infinity;

        if (dateTime == Time.Zero)
            return Zero;

        if (dateTime < DateTimeOffset.UnixEpoch.UtcDateTime)
            throw new Exception("explicit operator UnixTime(DateTime) : too low value");

        long ticks = new DateTimeOffset(dateTime).ToUnixTimeSeconds();

        if (ticks > int.MaxValue)
            throw new Exception("explicit operator UnixTime(DateTime) : too high value");
        return (UnixTime)(int)ticks;
    }

    public static Seconds operator -(UnixTime left, UnixTime right)
    {
        return (Seconds)(left.Seconds - right.Seconds);
    }

    public static UnixTime operator +(UnixTime left, Seconds right)
    {
        return (UnixTime)(left.Seconds + right.Ticks);
    }

    public static UnixTime operator -(UnixTime left, Seconds right)
    {
        return (UnixTime)(left.Seconds - right.Ticks);
    }

    public static bool operator >(UnixTime left, UnixTime right)
    {
        return left.Seconds > right.Seconds;
    }

    public static bool operator <(UnixTime left, UnixTime right)
    {
        return left.Seconds < right.Seconds;
    }

    public static bool operator >=(UnixTime left, UnixTime right)
    {
        return left.Seconds >= right.Seconds;
    }

    public static bool operator <=(UnixTime left, UnixTime right)
    {
        return left.Seconds <= right.Seconds;
    }
}

public readonly record struct UnixTime64
{
    public readonly long Seconds;
    public static readonly UnixTime64 Zero = new UnixTime64(0);
    public static readonly UnixTime64 Infinity = new UnixTime64(-1);

    public UnixTime64(long seconds)
    {
        if (seconds < 0 && seconds != -1)
            throw new Exception("constructor UnixTime64(long) : too low value");
        Seconds = seconds;
    }

    public static implicit operator long(UnixTime64 time)
    {
        return time.Seconds;
    }

    public static explicit operator UnixTime64(long seconds)
    {
        if (seconds < 0 && seconds != -1)
            throw new Exception("explicit operator UnixTime64(long) : too low value");
        return new UnixTime64(seconds);
    }

    public static explicit operator int(UnixTime64 time)
    {
        if (time.Seconds < 0 && time.Seconds != -1 || time.Seconds > int.MaxValue)
            throw new Exception("explicit operator int(UnixTime64) : out of range value");
        return (int)time.Seconds;
    }

    public static implicit operator UnixTime64(UnixTime time)
    {
        return (UnixTime64)time.Seconds;
    }

    public static explicit operator UnixTime64(UnixTimeMS time)
    {
        var seconds = time.Milliseconds / 1000;
        return (UnixTime64)seconds;
    }

    public static explicit operator DateTime(UnixTime64 time)
    {
        if (time == Infinity)
            return Time.Infinity;

        if (time == 0)
            return Time.Zero;

        return DateTimeOffset.FromUnixTimeSeconds(time).UtcDateTime;
    }

    public static explicit operator UnixTime64(DateTime dateTime)
    {
        if (dateTime == Time.Infinity)
            return Infinity;

        if (dateTime == Time.Zero)
            return Zero;

        if (dateTime < DateTimeOffset.UnixEpoch.UtcDateTime)
            throw new Exception("explicit operator UnixTime64(DateTime) : too low value");

        return (UnixTime64)new DateTimeOffset(dateTime).ToUnixTimeSeconds();
    }

    public static Seconds operator -(UnixTime64 left, UnixTime64 right)
    {
        return (Seconds)(left.Seconds - right.Seconds);
    }

    public static UnixTime64 operator +(UnixTime64 left, Seconds right)
    {
        return (UnixTime64)(left.Seconds + right.Ticks);
    }

    public static UnixTime64 operator -(UnixTime64 left, Seconds right)
    {
        return (UnixTime64)(left.Seconds - right.Ticks);
    }

    public static bool operator >(UnixTime64 left, UnixTime64 right)
    {
        return left.Seconds > right.Seconds;
    }

    public static bool operator <(UnixTime64 left, UnixTime64 right)
    {
        return left.Seconds < right.Seconds;
    }

    public static bool operator >=(UnixTime64 left, UnixTime64 right)
    {
        return left.Seconds >= right.Seconds;
    }

    public static bool operator <=(UnixTime64 left, UnixTime64 right)
    {
        return left.Seconds <= right.Seconds;
    }
}

public readonly record struct UnixTimeMS
{
    public readonly long Milliseconds;
    public static readonly UnixTimeMS Zero = new UnixTimeMS(0);
    public static readonly UnixTimeMS Infinity = new UnixTimeMS(-1);

    public UnixTimeMS(long milliseconds)
    {
        if (milliseconds < 0 && milliseconds != -1)
            throw new Exception("constructor UnixTimeMS(long) : too low value");
        Milliseconds = milliseconds;
    }

    public static implicit operator long(UnixTimeMS time)
    {
        return time.Milliseconds;
    }

    public static explicit operator UnixTimeMS(long milliseconds)
    {
        if (milliseconds < 0 && milliseconds != -1)
            throw new Exception("explicit operator UnixTimeMS(long) : too low value");
        return new UnixTimeMS(milliseconds);
    }

    public static explicit operator int(UnixTimeMS time)
    {
        if (time.Milliseconds < 0 && time.Milliseconds != -1 || time.Milliseconds > int.MaxValue)
            throw new Exception("explicit operator int(UnixTimeMS) : out of range value");
        return (int)time.Milliseconds;
    }

    public static implicit operator UnixTimeMS(UnixTime time)
    {
        long milliseconds = time.Seconds * 1000L;
        return (UnixTimeMS)milliseconds;
    }

    public static explicit operator UnixTimeMS(UnixTime64 time)
    {
        if (time.Seconds > long.MaxValue / 1000)
            throw new Exception("explicit operator UnixTimeMS(UnixTime64) : too high value");
        long milliseconds = time.Seconds * 1000L;
        return (UnixTimeMS)milliseconds;
    }

    public static explicit operator DateTime(UnixTimeMS time)
    {
        if (time == Infinity)
            return Time.Infinity;

        if (time == 0)
            return Time.Zero;

        return DateTimeOffset.FromUnixTimeSeconds(time).UtcDateTime;
    }

    public static explicit operator UnixTimeMS(DateTime dateTime)
    {
        if (dateTime == Time.Infinity)
            return Infinity;

        if (dateTime == Time.Zero)
            return Zero;

        if (dateTime < DateTimeOffset.UnixEpoch.UtcDateTime)
            throw new Exception("explicit operator UnixTimeMS(DateTime) : too low value");

        return (UnixTimeMS)new DateTimeOffset(dateTime).ToUnixTimeMilliseconds();
    }

    public static Seconds operator -(UnixTimeMS left, UnixTimeMS right)
    {
        return (Seconds)(left.Milliseconds - right.Milliseconds);
    }

    public static UnixTimeMS operator +(UnixTimeMS left, Seconds right)
    {
        return (UnixTimeMS)(left.Milliseconds + right.Ticks);
    }

    public static UnixTimeMS operator -(UnixTimeMS left, Seconds right)
    {
        return (UnixTimeMS)(left.Milliseconds - right.Ticks);
    }

    public static bool operator >(UnixTimeMS left, UnixTimeMS right)
    {
        return left.Milliseconds > right.Milliseconds;
    }

    public static bool operator <(UnixTimeMS left, UnixTimeMS right)
    {
        return left.Milliseconds < right.Milliseconds;
    }

    public static bool operator >=(UnixTimeMS left, UnixTimeMS right)
    {
        return left.Milliseconds >= right.Milliseconds;
    }

    public static bool operator <=(UnixTimeMS left, UnixTimeMS right)
    {
        return left.Milliseconds <= right.Milliseconds;
    }
}

public static class Time
{
    static Time()
    {
        ApplicationStartTime = Process.GetCurrentProcess().StartTime.ToUniversalTime();
        Zero = DateTime.MinValue;
        Infinity = DateTime.MaxValue;
    }

    public static readonly DateTime ApplicationStartTime;
    public static readonly TimeSpan StartLocalOffset;

    public static readonly Seconds Minute = (Seconds)60;
    public static readonly Seconds Hour = (Seconds)(Minute * 60);
    public static readonly Seconds Day = (Seconds)(Hour * 24);
    public static readonly Seconds Week = (Seconds)(Day * 7);
    public static readonly Seconds Month = (Seconds)(Day * 30);
    public static readonly Seconds Year = (Seconds)(Month * 12);
    public static readonly Milliseconds InMilliseconds = (Milliseconds)1000;

    public static readonly DateTime Zero;
    public static readonly DateTime Infinity;

    /// <summary>
    /// Gets the current local time.
    /// </summary>
    public static DateTimeOffset NowLocal => DateTimeOffset.Now;

    /// <summary>
    /// Gets the current UTC time.
    /// </summary>
    public static DateTime Now => DateTime.UtcNow;

    /// <summary>
    /// Gets the application UpTime.
    /// </summary>
    public static TimeSpan UpTime => Now - ApplicationStartTime;

    /// <summary>
    /// Gets the application time relative to application start time in ms.
    /// </summary>
    public static RelativeTime NowRelative => (RelativeTime)UpTime.ToMilliseconds();

    /// <summary>
    /// Gets the difference to current UTC time.
    /// </summary>
    public static TimeSpan Diff(DateTime oldTime)
    {
        return Diff(oldTime, Now);
    }    

    /// <summary>
    /// Gets the difference to current UpTime.
    /// </summary>
    public static TimeSpan Diff(TimeSpan oldUpTime)
    {
        return UpTime - oldUpTime;
    }

    /// <summary>
    /// Gets the difference to current RelativeTime in milliseconds.
    /// </summary>
    public static Milliseconds Diff(RelativeTime oldMSTime)
    {
        return Diff(oldMSTime, NowRelative);
    }

    /// <summary>
    /// Gets the difference between two time points.
    /// </summary>
    public static TimeSpan Diff(DateTime oldTime, DateTime newTime)
    {
        return newTime - oldTime;
    }

    /// <summary>
    /// Gets the difference between two time spans.
    /// </summary>
    public static TimeSpan Diff(TimeSpan oldTimeSpan, TimeSpan newTimeSpan)
    {
        return newTimeSpan - oldTimeSpan;
    }

    /// <summary>
    /// Gets the difference between two relative to UpTime spans in milliseconds.
    /// </summary>
    public static Milliseconds Diff(RelativeTime oldMSTime, RelativeTime newMSTime)
    {
        if (oldMSTime > newMSTime)
            return (Milliseconds)((RelativeTime)0xFFFFFFFF - oldMSTime + newMSTime);
        else
            return (Milliseconds)(newMSTime - oldMSTime);
    }
}

是的,所有这些类型都被使用,我无法摆脱它们。一部分在数据库,一部分在客户端,一部分在服务器。

Я понял что при передаче в функцию особо ничего не меняет 4 или 8 байт особенно учитывая х64 систему. Но есть в коде куча переменных с какимито таймерами или оперативными настройками, где хранится от 0 до 1 часа времени. Если сделать все 8 байт - размеры классов вырастут вдвое и втрое, а они все подвязаны к количеству клиентов онлайн. Так что расходы реально возрастают.

П.С. В коде проблема с 2038 годом решена тем, что в клиенте используется relative time 4байта. Экономия места как бы + оверфлов раз в месяц при стабильном аптайме (который правильно считает разницу). Естественно используется для какой-то ерунды. Там где нужно точно передать дату - используют 8байт, но UnixTime исключительно. Проблема же 2038 в коде сервера и базы данных пока не решена, но похоже пока это откладывается до 2038.

Показанный код - это все новое. В коде это просто int uint long + иногда комментарии или захардкоржено в имени переменной/метода. Распутываю до сих пор и нахожу даже баги, когда в sec пихали ms

И да, в самой базе данных все хранится в uint/ulong, а в коде используется все разнообразие. -1 => uint.MaxValue - вот так захардкоржено и все)

c#
  • 1 个回答
  • 106 Views
Martin Hope
Artem
Asked: 2022-08-21 17:33:40 +0000 UTC

Bool 方法逻辑 Enum.HasFlag(Enum enum)

  • 0

MSDN 声明如下:

    bool Enum.HasFlag(Enum enum)
    {
        return (thisInstance & enum) == enum;
    }

问题:为什么将按位“AND”的结果与所需的标志进行比较,如果你可以这样做:

   return (thisInstance & enum) != 0;

或像这样:

   return (bool)(thisInstance & enum);//так не работает в С#

避免显式/隐式类型转换?(但使用按位运算,仍然存在到 Int32 或 Int64 的隐式转换)

只是这在任何地方都没有解释,但这个问题很有趣,因为在所有示例中(甚至是 HasFlag 的手动实现 - 无处不在 (thisInstance & enum) == enum )。

所以我想知道由于一些内置的 CLR 函数,性能是否更高,还是优化更好?

我们目前正在创建重复代码!!(好吧,如果我们谈论的话)

c# enum
  • 2 个回答
  • 49 Views
Martin Hope
Artem
Asked: 2022-08-12 09:37:43 +0000 UTC

C 字符串复制函数的流行表达式的正确性 { while (*dest++ = *src++) }

  • 7

我开始阅读 A.V. 的教科书“编程:专业介绍”第 2 卷“系统和网络”。Stolyarov,处理 C 编程语言。在关于指针和字符串数组的主题(第 96 页)中,有一个小例子说明了从一个字符串复制到另一个字符串的过程的实现。实际上,代码如下所示(第 94 页还有另一个示例):

    void stringCopy(char* dest, const char* src)
    {
        while ((*dest++ = *src++));    
    }

作者坚持认为代码有错误。而且,这个例子本身经常在网上闪现为“超短解”,笔者对此持否定态度。作者本人并没有指出具体的错误,但是,他要求(为自己)理解,只是暗示了一个容易忽略的副作用。 本教程作者的正确代码示例如下所示:这是作者写的。 在此处输入图像描述

     while (*src)
     {
         *dest = *src;
         dest++;
         src++;
     }
     *dest = '\0'

实际上,我一直在寻找至少一些提及此代码中的错误,但没有人感兴趣,除了代码的原理。一般来说,如果您了解操作的优先级,那么一切都会到位(我一开始超频时是这样认为的):

1. 事实证明,后缀递增/递减与前缀类似物的实现方式不同。这肯定解释了错误代码的操作。我检查了它100%有效。https://ravesli.com/urok-40-inkrement-dekrement-pobochnye-effekty/

#include <stdlib.h>
void stringCopy(char* dest, const char* src)
{
    while ((*dest++ = *src++));// почему-то неправильная запись с ошибкой (хотя все работает)
    /*
    Правильная запись
    while (*src)
    {
        *dest = *src;
        dest++;
        src++;
    }
    *dest = '\0';
    */
}
int main()
{
    char* src = malloc(15);
    char* dest = malloc(15);
    *(src + 0) = '\0';
    *(src + 1) = 'e';
    *(src + 2) = 'a';
    *(src + 3) = 'r';
    *(src + 4) = '!';
//дальше не продолжал инициализацию - Visual Studio туда помещает 
//мусор без нулей
    
    stringCopy(dest, src);
//вот тут я поставил точку останова в дебаггере - мои указатели 
//ссылаются на нулевые строки (значит копирование успешно прошло при нулевой строке и значит что ошибка не в операторе постфиксного инкремента)
    free(src);
    free(dest);
}

2. 最后,我似乎弄明白了“left-admissible”表达式的概念(第 87 页)。原来后缀递增和递减的实现的唯一性,和这个“左可容性”的概念有直接关系?还是分开的?让它完全正确。

因此,尚不清楚那里是否存在错误。事实证明,问题出在这段代码的可见性上,最好把所有东西都写得很漂亮放在架子上,因为你永远不知道什么会撞到编译器,或者很难分析代码?并且发明了错误 - 打破寻找它并引导他得出这个结论的人的大脑?

更新:没有错误。错误出现在第 94 页的示例中(显然作者的错误是计算长度时考虑了行尾符号,尽管这甚至不是规则)。在我看来,由于他的笔记风格是十字形的,那里肯定也有一个错误。作者只是想表明这不值得做。在这种情况下,代码的紧凑性导致难以理解正在发生的事情。

Upd:继续深入研究这本书,我遇到了第100-103段“Sequence points”。当然,我没有那么多经验,我想听听那里所说的情况是否发生在这种情况下。好吧,既然没有人回答“左可接受的表达” - 也许有人会在这种情况下谈论它们。

c
  • 1 个回答
  • 10 Views

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5