|
// 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.
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;
}
}
|