2015-09-24 17 views
5

Một số phương thức .NET sử dụng tham số StringComparison, một số sử dụng StringComparer (thường ở dạng IComparer). Sự khác biệt là rõ ràng. Có cách nào thanh lịch để nhận được StringComparison từ StringComparer hoặc ngược lại?Cách thanh lịch để chuyển đổi giữa StringComparison và StringComparer?

Tôi luôn có thể viết phương pháp đơn giản sử dụng câu lệnh Case, nhưng có lẽ đã có thứ gì đó có trong .NET những gì tôi đang xem.

Trả lời

6

Đi StringComparison-StringComparer rất đơn giản - chỉ cần tạo một Dictionary<StringComparison, StringComparer>:

var map = new Dictionary<StringComparison, StringComparer> 
{ 
    { StringComparison.Ordinal, StringComparer.Ordinal }, 
    // etc 
}; 

Có một StringComparer cho mỗi giá trị StringComparison, do đó cách đó hoạt động thực sự dễ dàng. Tâm trí bạn, StringComparer.CurrentCulture phụ thuộc vào văn bản chủ đề hiện tại - vì vậy nếu bạn điền từ điển và sau đó sửa đổi văn bản của chuỗi (hoặc thực hiện nó từ một luồng khác với một nền văn hóa khác), bạn có thể kết thúc với giá trị sai. Bạn có khả năng muốn có một Dictionary<StringComparison, Func<StringComparer>>:

var map = new Dictionary<StringComparison, Func<StringComparer>> 
{ 
    { StringComparison.Ordinal,() => StringComparer.Ordinal }, 
    // etc 
}; 

Sau đó, bạn có thể nhận được một Comparer bất cứ lúc nào bằng cách gọi các đại biểu:

var comparer = map[comparison](); 

Đi theo cách khác là không khả thi, bởi vì không phải mọi StringComparer một phù hợp StringComparison. Ví dụ, giả sử tôi (ở Anh) tạo ra một StringComparer cho Pháp (StringComparer.Create(new CultureInfo(..., true)). Mà StringComparison không đại diện cho? Đó không phải là chính xác cho các nền văn hóa hiện nay, văn hóa bất biến, hoặc so sánh thứ tự.

+0

Cảm ơn bạn đã cho thấy rằng "bản đồ động" hữu ích khi văn hóa có khả năng thay đổi. Có lẽ tôi cũng hiểu tại sao mọi thứ không đơn giản như vậy. NET sẽ cung cấp nó ra khỏi hộp. – miroxlav

6

Không có một cái gì đó ra khỏi hộp, nhưng bạn có thể tạo ra một bản đồ đơn giản cho mình giữa comparsion và Comparer:

Dictionary<StringComparison, StringComparer> comparsionToComparer = 
         new Dictionary<StringComparison, System.StringComparer> 
{ 
    { StringComparison.CurrentCulture, StringComparer.CurrentCulture }, 
    { StringComparison.CurrentCultureIgnoreCase, StringComparer.CurrentCultureIgnoreCase }, 
    { StringComparison.InvariantCulture, StringComparer.InvariantCulture }, 
    { StringComparison.InvariantCultureIgnoreCase, StringComparer.InvariantCultureIgnoreCase }, 
    { StringComparison.Ordinal, StringComparer.Ordinal }, 
    { StringComparison.OrdinalIgnoreCase, StringComparer.OrdinalIgnoreCase } 
} 

Và khi chưa từng có bạn cần Comparer thích hợp:

var invariantComparer = comparsionToComparer[StringComparsion.InvariantCulture]; 

Edit:

Với C# -6 điển Initializer cú pháp:

Dictionary<StringComparison, StringComparer> comparsionToComparer = 
          new Dictionary<StringComparison, System.StringComparer> 
{ 
    [StringComparison.CurrentCulture] = StringComparer.CurrentCulture, 
    [StringComparison.CurrentCultureIgnoreCase] = StringComparer.CurrentCultureIgnoreCase, 
    [StringComparison.InvariantCulture] = StringComparer.InvariantCulture, 
    [StringComparison.InvariantCultureIgnoreCase] = StringComparer.InvariantCultureIgnoreCase, 
    [StringComparison.Ordinal] = StringComparer.Ordinal, 
    [StringComparison.OrdinalIgnoreCase] = StringComparer.OrdinalIgnoreCase 
}; 

Ngoài ra, Jons answer đề cập đến vấn đề của chủ đề hiện văn hóa, mà tôi bỏ đi và có lẽ nên được đưa vào tài khoản

+0

Vâng, đây là những gì tôi sắp làm.Trước khi viết mã, tôi đã hỏi liệu .NET có một cái gì đó như thế này đã được bên trong. – miroxlav

+0

@miroxlav Không có bản đồ hiện có mà tôi biết. –

+0

Dựa trên câu trả lời của Jon Tôi nghĩ rằng có lẽ tôi hiểu tại sao không có thứ gì như thế. Nó có thể không đơn giản như nó xuất hiện ngay từ cái nhìn đầu tiên. – miroxlav

1

phiên bản dựa trên câu trả lời được chấp nhận (và Option Infer Off):

Dim map As New Dictionary(Of StringComparison, Func(Of StringComparer))() _ 
    From { 
     {StringComparison.CurrentCulture, Function() StringComparer.CurrentCulture}, 
     {StringComparison.CurrentCultureIgnoreCase, Function() StringComparer.CurrentCultureIgnoreCase}, 
     {StringComparison.InvariantCulture, Function() StringComparer.InvariantCulture}, 
     {StringComparison.InvariantCultureIgnoreCase, Function() StringComparer.InvariantCultureIgnoreCase}, 
     {StringComparison.Ordinal, Function() StringComparer.Ordinal}, 
     {StringComparison.OrdinalIgnoreCase, Function() StringComparer.OrdinalIgnoreCase} 
    } 

Cách sử dụng:

Dim comparer As StringComparer = map(comparison)() 
0

một hoàn toàn phương pháp mở rộng cho bất kỳ ai cần bản sao chép nhanh + dán:

public static class StringComparisonExtensions 
{ 
    // from http://stackoverflow.com/a/32764112/548304 
    private static readonly Dictionary<StringComparison, Func<StringComparer>> ComparsionToComparer = 
    new Dictionary<StringComparison, Func<StringComparer>> 
     { 
     [StringComparison.CurrentCulture] =() => StringComparer.CurrentCulture, 
     [StringComparison.CurrentCultureIgnoreCase] =() => StringComparer.CurrentCultureIgnoreCase, 
     [StringComparison.InvariantCulture] =() => StringComparer.InvariantCulture, 
     [StringComparison.InvariantCultureIgnoreCase] =() => StringComparer.InvariantCultureIgnoreCase, 
     [StringComparison.Ordinal] =() => StringComparer.Ordinal, 
     [StringComparison.OrdinalIgnoreCase] =() => StringComparer.OrdinalIgnoreCase 
     }; 

    /// <summary> 
    /// Retrieves a string comparer for the given StringComparison. 
    /// </summary> 
    public static StringComparer ToComparer(this StringComparison comparison) 
    { 
    return ComparsionToComparer.GetValueOrDefault(comparison)?.Invoke(); 
    } 
} 
Các vấn đề liên quan