-
Notifications
You must be signed in to change notification settings - Fork 4k
/
LocalizableString.cs
133 lines (116 loc) · 4.01 KB
/
LocalizableString.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
namespace Microsoft.CodeAnalysis
{
/// <summary>
/// A string that may possibly be formatted differently depending on culture.
/// NOTE: Types implementing <see cref="LocalizableString"/> must be serializable.
/// </summary>
public abstract partial class LocalizableString : IFormattable, IEquatable<LocalizableString?>
{
/// <summary>
/// Fired when an exception is raised by any of the public methods of <see cref="LocalizableString"/>.
/// If the exception handler itself throws an exception, that exception is ignored.
/// </summary>
public event EventHandler<Exception>? OnException;
/// <summary>
/// Formats the value of the current instance using the optionally specified format.
/// </summary>
public string ToString(IFormatProvider? formatProvider)
{
try
{
return GetText(formatProvider);
}
catch (Exception ex)
{
RaiseOnException(ex);
return string.Empty;
}
}
public static explicit operator string?(LocalizableString localizableResource)
{
return localizableResource.ToString(null);
}
public static implicit operator LocalizableString(string? fixedResource)
{
return FixedLocalizableString.Create(fixedResource);
}
public sealed override string? ToString()
{
return ToString(null);
}
string? IFormattable.ToString(string? ignored, IFormatProvider? formatProvider)
{
return ToString(formatProvider);
}
public sealed override int GetHashCode()
{
try
{
return GetHash();
}
catch (Exception ex)
{
RaiseOnException(ex);
return 0;
}
}
public sealed override bool Equals(object? other)
{
try
{
return AreEqual(other);
}
catch (Exception ex)
{
RaiseOnException(ex);
return false;
}
}
public bool Equals(LocalizableString? other)
{
return Equals((object?)other);
}
/// <summary>
/// Formats the value of the current instance using the optionally specified format.
/// Provides the implementation of ToString. ToString will provide a default value
/// if this method throws an exception.
/// </summary>
protected abstract string GetText(IFormatProvider? formatProvider);
/// <summary>
/// Provides the implementation of GetHashCode. GetHashCode will provide a default value
/// if this method throws an exception.
/// </summary>
/// <returns></returns>
protected abstract int GetHash();
/// <summary>
/// Provides the implementation of Equals. Equals will provide a default value
/// if this method throws an exception.
/// </summary>
/// <returns></returns>
protected abstract bool AreEqual(object? other);
private void RaiseOnException(Exception ex)
{
if (ex is OperationCanceledException)
{
return;
}
try
{
OnException?.Invoke(this, ex);
}
catch
{
// Ignore exceptions from the exception handlers themselves.
}
}
/// <summary>
/// Flag indicating if any methods on this type can throw exceptions from public entrypoints.
/// </summary>
internal virtual bool CanThrowExceptions => true;
}
}