Cách tốt nhất để lưu trữ một nhóm hằng số mà chương trình của tôi sử dụng là gì? [đóng cửa]


97

Tôi có nhiều hằng số khác nhau mà chương trình của tôi sử dụng ... string's, int' s, double's, v.v. ... Cách tốt nhất để lưu trữ chúng là gì? Tôi không nghĩ rằng tôi muốn một Enum, bởi vì dữ liệu không phải là tất cả cùng một loại và tôi muốn đặt từng giá trị theo cách thủ công. Tôi có nên lưu trữ tất cả chúng trong một lớp trống không? đây có phải là cách tốt hơn không?


18
Bất cứ cách nào bạn muốn - đó là cách bạn cần.
San Jacinto

Câu trả lời:


135

Bạn có thể có chúng trong một lớp tĩnh, với các thuộc tính chỉ đọc tĩnh.

public static class Routes
{
    public static string SignUp => "signup";
}

23
+1, nhưng thậm chí còn tốt hơn nếu bạn có thể lấy những thứ này từ tệp tài nguyên để bản địa hóa.
Joel Coehoorn

17
Có vẻ hơi dài dòng - tại sao không phải là chuỗi tĩnh chỉ đọc?
blankset

6
Tại sao chỉ đọc mà không phải const? Bạn không đặt giá trị trong thời gian chạy, vì vậy không cần phải đặt chúng ở dạng chỉ đọc.
Philip Wallace

91
Vấn đề với const là bất kỳ hội đồng nào được biên dịch chống lại các consts sẽ nhận được bản sao cục bộ của những consts đó khi bản thân chúng được biên dịch; vì vậy nếu bạn thay đổi một giá trị, bạn cũng phải biên dịch lại tất cả các hợp ngữ phụ thuộc vào hợp ngữ của bạn xác định các hằng số - do đó thường an toàn hơn khi đi theo lộ trình chỉ đọc. Thuộc tính thay vì giá trị tĩnh công khai cho phép bạn linh hoạt thêm một số logic lập trình trong tương lai nếu bạn cần (tức là đọc từ bản địa hóa) mà không cần thay đổi giao diện thành các giá trị không đổi của bạn.
cfeduke

11
Là người ủng hộ ma quỷ, tôi phải chỉ ra rằng lợi thế của const là bạn có thể sử dụng nó trong các trường hợp chuyển đổi.
arviman

27

IMO sử dụng một lớp đầy hằng số là tốt cho hằng số. Nếu chúng thỉnh thoảng thay đổi, tôi khuyên bạn nên sử dụng AppSettings trong cấu hình của bạn và thay vào đó là lớp ConfigurationManager.

Khi tôi có "hằng số" thực sự được kéo vào từ AppSettings hoặc tương tự, tôi vẫn sẽ luôn có một lớp "hằng số" bao bọc việc đọc từ trình quản lý cấu hình. Luôn có ý nghĩa hơn nếu có Constants.SomeModule.Settingthay vì phải trực tiếp đến ConfigurationManager.AppSettings["SomeModule/Setting"]bất kỳ nơi nào muốn tiêu thụ giá trị cài đặt đã nói.

Điểm thưởng cho thiết lập này, vì SomeModulecó thể là một lớp lồng nhau bên trong tệp Hằng số, bạn có thể dễ dàng sử dụng Dependency Injection để đưa SomeModuletrực tiếp vào các lớp phụ thuộc vào nó. Bạn thậm chí có thể trích xuất một giao diện trên đầu trang SomeModulevà sau đó tạo một ISomeModuleConfigurationphần phụ thuộc vào mã tiêu thụ của bạn, điều này sau đó sẽ cho phép bạn tách phần phụ thuộc vào các tệp Constants và thậm chí có khả năng làm cho việc kiểm tra dễ dàng hơn, đặc biệt nếu các cài đặt này đến từ AppSettings và bạn thay đổi chúng bằng cách sử dụng chuyển đổi cấu hình vì cài đặt là môi trường cụ thể.


1
Chỉ cần thêm vào điều này: lý do là khi bạn xây dựng, các hằng số được sử dụng từ các hội đồng khác không được cập nhật. Điều này có nghĩa là nếu bạn có AssemblyA và AssemblyB và B sử dụng một hằng số từ A, giá trị được sao chép, không được tham chiếu, vì vậy việc xây dựng lại A sẽ không cập nhật B. Điều này có thể dẫn đến các lỗi kỳ lạ.
Camilo Martin

1
@CamiloMartin có rất nhiều cách để xử lý điều đó, "hằng số" của bạn có thể chỉ đọc tĩnh để tránh điều đó hoặc như tôi đã nói nếu chúng thay đổi nhiều lần trong một lần trăng xanh để sử dụng ConfigurationManager.
Chris Marisic

Vâng, tôi chỉ nói rằng không chỉ vì đó là một quy ước mà bạn nên sử dụng static chỉ đọc, mà vì nó thực sự có thể là một nguồn gây nhầm lẫn. Ngoài ra, một giải pháp thay thế cho ConfigurationManager là các tệp tài nguyên - bạn chỉ cần thêm một tệp tài nguyên khác có mã ngôn ngữ trong tên và mã của bạn được bản địa hóa ngay lập tức.
Camilo Martin

vấn đề là khi bạn tham khảo này lắp ráp từ hội đồng khác, bạn sẽ phải sao chép các giá trị vào các tập tin cấu hình của họ
vật cộng sinh

@symbiont bạn có thể nhúng các file cấu hình và đọc chúng ra khỏi manifest thay vì nếu bạn muốn, cho sharability như một thành phần bên thứ 3
Chris Marisic

19

Những gì tôi muốn làm là như sau (nhưng hãy nhớ đọc đến cuối để sử dụng loại hằng số thích hợp ):

internal static class ColumnKeys
{
    internal const string Date = "Date";
    internal const string Value = "Value";
    ...
}

Đọc phần này để biết tại sao constcó thể không như bạn muốn. Thể loại hằng số là:

  • constlĩnh vực. Không sử dụng trên các tập hợp ( publichoặc protected) nếu giá trị có thể thay đổi trong tương lai vì giá trị sẽ được mã hóa cứng tại thời điểm biên dịch trong các tập hợp khác đó. Nếu bạn thay đổi giá trị, giá trị cũ sẽ được sử dụng bởi các tập hợp khác cho đến khi chúng được biên dịch lại.
  • static readonly lĩnh vực
  • static tài sản không có set

1
Tại sao chỉ đọc nếu được sử dụng trên nhiều cụm?
Philip Wallace

Tại sao static chỉ đọc hoạt động tốt hơn với nhiều hội đồng hơn là const?
Matthew

15
Giá trị Const được sao chép từ lắp ráp nguồn vào mã đã biên dịch. Điều này có nghĩa là nếu bạn phải thay đổi giá trị const, tất cả các cụm phụ thuộc PHẢI được biên dịch lại so với phiên bản mới. An toàn hơn và thuận tiện hơn khi sử dụng static readonly.
cfeduke

6
Lợi ích của const là chúng có thể được sử dụng trong một công tắc
knaki02

11

Đây là cách tốt nhất IMO. Không cần thuộc tính hoặc chỉ đọc:

public static class Constants
{
   public const string SomeConstant = "Some value";
}

9
Nếu bạn định sử dụng const, hãy chỉ hiển thị dưới dạng nội bộ. Không công khai const (ngay cả khi bạn nghĩ rằng các tập hợp của bạn sẽ không được sử dụng bên ngoài tổ chức của bạn). Ngoài ra, các thuộc tính cung cấp cho bạn tính linh hoạt trong lập trình để mở rộng trong tương lai mà không cần phải xác định lại giao diện của bạn.
cfeduke

4

Một lớp tĩnh trống là thích hợp. Hãy cân nhắc sử dụng một số lớp để bạn có được các nhóm hằng số liên quan tốt chứ không phải một tệp Globals.cs khổng lồ.

Ngoài ra, đối với một số hằng số int, hãy xem xét ký hiệu:

[Flags]
enum Foo
{
}

Vì điều này cho phép xử lý các giá trị như cờ .


"Hãy xem xét sử dụng một số lớp để bạn kết thúc với các nhóm hằng số có liên quan tốt chứ không phải một tệp Globals.cs khổng lồ." Tôi tin rằng đây là khuyến nghị tốt nhất, không có một số mẫu thiết kế xung quanh điều này? Tôi không biết tên nào, phải không?
greg

3

Một phiếu bầu khác cho việc sử dụng web.config hoặc app.config. Các tệp cấu hình là một nơi tốt cho các hằng số như chuỗi kết nối, v.v. Tôi không muốn phải nhìn vào nguồn để xem hoặc sửa đổi những loại này. Một lớp tĩnh đọc các hằng số này từ tệp .config có thể là một sự thỏa hiệp tốt, vì nó sẽ cho phép ứng dụng của bạn truy cập các tài nguyên này như thể chúng đã được định nghĩa trong mã, nhưng vẫn cung cấp cho bạn sự linh hoạt khi có chúng trong một tệp có thể xem / chỉnh sửa dễ dàng không gian.


2
Một chuỗi kết nối không phải là một hằng số, nó là một cài đặt. Có thể OP thực sự cũng có nghĩa là cài đặt, chứ không phải là hằng số, nhưng tôi không thấy bất kỳ bằng chứng nào cho điều đó.
Jon Skeet

Tôi có ý kiến ​​khác. Các chuỗi ký tự là hằng số theo định nghĩa. Thay đổi chuỗi trong tệp cấu hình gần tương đương với việc thay đổi chuỗi trong mã và biên dịch lại; điều đó sẽ làm cho nó không phải là một hằng số? Tôi không nghĩ vậy.
3Dave,

2
@David - Không đúng. Trình biên dịch không quan tâm đến giá trị bạn có trong tệp cấu hình của mình - giá trị này được đọc trong thời gian chạy.
Philip Wallace

@PhilipW Tôi hiểu điều đó. Quan điểm của tôi là (theo nhận xét của Jon Skeet) một chuỗi kết nối cụ thể là một hằng số, như tất cả các ký tự của chuỗi. Thực tế là một "hằng số" có thể được thay đổi - bằng cách sửa đổi tệp cấu hình và để ứng dụng của bạn lấy giá trị mới từ tệp cấu hình đã nói hoặc bằng cách thay đổi ký tự trong mã sẽ yêu cầu biên dịch lại / triển khai - không biến nó thành một "thiết lập". Bản thân chuỗi là hằng số bất kể vùng chứa của nó. Tôi hiểu và đồng ý với quan điểm của bạn - đó không phải là những gì tôi đã nói.
3Dave

1
Theo kinh nghiệm của tôi, tại một số thời điểm trong tương lai không lường trước, giá trị "không đổi" của bạn sẽ cần phải thay đổi ngay cả khi bạn nghĩ rằng nó sẽ không bao giờ xảy ra trong một triệu năm. Tôi nghĩ điều này dễ thực hiện trong tệp .config hơn nhiều so với việc thay đổi mã nguồn. Cuối cùng thì mọi thứ đều trở thành một sự sắp đặt.
NinjaBomb,

1

Có, a static classđể lưu trữ các hằng số sẽ tốt, ngoại trừ các hằng số liên quan đến các kiểu cụ thể.


đó chính xác là những gì tôi đang cố gắng làm. tôi muốn họ xuất hiện với tư cách là thành viên của lớp học mà họ dành cho. nhưng tôi không muốn thêm chúng vào các lớp vì các hằng số khác nhau tùy thuộc vào công ty tôi đang làm việc. tôi chưa tìm thấy bất cứ điều gì về hằng số hoặc thuộc tính mở rộng. nhưng tôi có thể từ bỏ ý tưởng này bởi vì tôi không muốn họ xuất hiện như các thành viên khi tôi serialize các lớp này
vật cộng sinh

0

Nếu các Hằng số này là tham chiếu dịch vụ hoặc công tắc ảnh hưởng đến hành vi ứng dụng, tôi sẽ thiết lập chúng làm cài đặt người dùng Ứng dụng. Bằng cách đó, nếu chúng cần được thay đổi, bạn không phải biên dịch lại và bạn vẫn có thể tham chiếu chúng thông qua lớp thuộc tính tĩnh.

Properties.Settings.Default.ServiceRef

0

Tôi sẽ đề xuất lớp tĩnh với chỉ đọc tĩnh. Vui lòng tìm đoạn mã bên dưới:

  public static class CachedKeysManager
    {
        public static readonly string DistributorList = "distributorList";
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.