Đã có một vài câu trả lời ở đây, nhưng đây là câu trả lời có tính đến Unity3D (câu trả lời rất cụ thể đối với Unity3D, tôi sẽ làm hầu hết những điều này rất khác nhau trong hầu hết các bối cảnh):
Nói chung, Unity3D không sử dụng ngoại lệ theo truyền thống. Nếu bạn ném một ngoại lệ vào Unity3D, thì không có gì giống như trong ứng dụng .NET trung bình của bạn, cụ thể là nó sẽ không dừng chương trình, hầu hết bạn có thể định cấu hình trình chỉnh sửa để tạm dừng. Nó sẽ chỉ được đăng nhập. Điều này có thể dễ dàng đưa trò chơi vào trạng thái không hợp lệ và tạo hiệu ứng xếp tầng khiến các lỗi khó theo dõi. Vì vậy, tôi muốn nói trong trường hợp của Unity, cho phép Add
ném một ngoại lệ là một lựa chọn đặc biệt không mong muốn.
Nhưng trong việc kiểm tra tốc độ của các ngoại lệ không phải là trường hợp tối ưu hóa sớm trong một số trường hợp vì cách Mono hoạt động trong Unity trên một số nền tảng. Trên thực tế, Unity3D trên iOS hỗ trợ một số tối ưu hóa tập lệnh nâng cao và các ngoại lệ bị vô hiệu hóa * là tác dụng phụ của một trong số chúng. Đây thực sự là một cái gì đó để xem xét bởi vì những thiên đường tối ưu hóa đã được chứng minh rất có giá trị đối với nhiều người dùng, cho thấy một trường hợp thực tế để xem xét việc giới hạn việc sử dụng các ngoại lệ trong Unity3D. (* ngoại lệ được quản lý từ công cụ, không phải mã của bạn)
Tôi muốn nói rằng trong Unity bạn có thể muốn có một cách tiếp cận chuyên biệt hơn. Trớ trêu thay, một câu trả lời rất được bình chọn tại thời điểm viết bài này , cho thấy một cách tôi có thể thực hiện một cái gì đó như thế này cụ thể trong bối cảnh của Unity3D (ở một nơi khác như thế này thực sự không thể chấp nhận được, và ngay cả trong Unity, nó khá không phù hợp).
Một cách tiếp cận khác mà tôi xem xét là thực sự không chỉ ra lỗi do người gọi quan tâm, mà là sử dụng các Debug.LogXX
chức năng. Bằng cách đó, bạn có được hành vi tương tự như ném một ngoại lệ chưa được xử lý (vì cách Unity3D xử lý chúng) mà không mạo hiểm đặt một cái gì đó vào trạng thái lạ xuống dòng. Ngoài ra hãy xem xét nếu đây thực sự là một lỗi (Việc cố gắng tải cùng một tài liệu hai lần có nhất thiết là một lỗi trong trường hợp của bạn không? Hoặc đây có thể là trường hợp Debug.LogWarning
được áp dụng nhiều hơn).
Và liên quan đến việc sử dụng những thứ như Debug.LogXX
hàm thay vì ngoại lệ, bạn vẫn phải xem xét điều gì xảy ra khi một ngoại lệ sẽ được ném từ thứ gì đó trả về giá trị (như GetM vật liệu). Tôi có xu hướng tiếp cận điều này bằng cách chuyển null cùng với việc ghi lại lỗi ( một lần nữa, chỉ trong Unity ). Sau đó, tôi sử dụng kiểm tra null trong MonoBehaviors của mình để đảm bảo mọi phụ thuộc như vật liệu không phải là giá trị null và vô hiệu hóa MonoBehavior nếu có. Một ví dụ cho một hành vi đơn giản đòi hỏi một vài phụ thuộc là như thế này:
public void Awake()
{
_inputParameters = GetComponent<VehicleInputParameters>();
_rigidbody = GetComponent<Rigidbody>();
_rigidbodyTransform = _rigidbody.transform;
_raycastStrategySelector = GetComponent<RaycastStrategySelectionBehavior>();
_trackParameters =
SceneManager.InstanceOf.CurrentSceneData.GetValue<TrackParameters>();
this.DisableIfNull(() => _rigidbody);
this.DisableIfNull(() => _raycastStrategySelector);
this.DisableIfNull(() => _inputParameters);
this.DisableIfNull(() => _trackParameters);
}
SceneData.GetValue<>
tương tự như ví dụ của bạn ở chỗ nó gọi một hàm trên từ điển đưa ra một ngoại lệ. Nhưng thay vì ném một ngoại lệ, nó sử dụng Debug.LogError
một dấu vết ngăn xếp như một ngoại lệ bình thường và trả về null. Các kiểm tra theo sau * sẽ vô hiệu hóa hành vi thay vì để nó tiếp tục tồn tại ở trạng thái không hợp lệ.
* các kiểm tra trông như thế bởi vì một người trợ giúp nhỏ tôi sử dụng để in ra một thông báo được định dạng khi nó vô hiệu hóa đối tượng trò chơi **. Kiểm tra null đơn giản với if
công việc ở đây (** séc của người trợ giúp chỉ được biên dịch trong các bản dựng Debug (như xác nhận). Sử dụng lambdas và các biểu thức như thế trong Unity có thể gây ảnh hưởng đến hiệu suất)
_Materials.Add
ném một ngoại lệ?