Programming

* 정적 일 수있는 * C # 메서드는 정적이어야합니까?

procodes 2020. 8. 17. 11:47
반응형

* 정적 일 수있는 * C # 메서드는 정적이어야합니까? [닫은]


정적 일 있는 C # 메서드는 정적이어야합니까?

우리는 오늘 이것에 대해 논의하고 있었고 나는 일종의 울타리에 있습니다. 몇 줄을 리팩토링하는 긴 방법이 있다고 상상해보십시오. 새 메서드는 부모 메서드에서 몇 개의 지역 변수를 가져와 값을 반환합니다. 이것은 정적 있음을 의미합니다 .

문제는 정적 이어야 합니까? 인스턴스 값을 참조하지 않는다는 점에서 본질적으로 설계 나 선택에 따라 정적 인 것이 아닙니다.


때에 따라 다르지. 실제로 두 가지 유형의 정적 메서드가 있습니다.

  1. 될 수 있기 때문에 정적 메서드
  2. 정적이어야하기 때문에 정적 메서드

중소 규모의 코드베이스에서는 두 가지 방법을 서로 바꿔서 사용할 수 있습니다.

첫 번째 범주 (정적 일 수 있음)에있는 메서드가 있고 클래스 상태에 액세스하도록 변경해야하는 경우 정적 메서드를 인스턴스 메서드로 전환 할 수 있는지 확인하는 것은 비교적 간단합니다.

그러나 대규모 코드 기반에서는 많은 수의 호출 사이트가 정적 메서드를 비 정적 메서드로 변환하는 것이 가능한지 너무 비용이 많이 드는지 확인하기 위해 검색을 수행 할 수 있습니다. 여러 번 사람들은 호출 횟수를보고 "좋아 ...이 방법을 변경하지 않는 것이 좋지만 필요한 작업을 수행하는 새 방법을 만드는 것이 좋습니다."라고 말합니다.

결과는 다음 중 하나 일 수 있습니다.

  1. 많은 코드 중복
  2. 메서드 인수 수의 급증

둘 다 나쁘다.

그래서 제 충고는 만약 당신이 200K LOC 이상의 코드 기반을 가지고 있다면, 그것이 반드시 정적이어야 할 경우에만 정적 메서드를 만들 것이라는 것입니다.

비 정적에서 정적으로 리팩토링하는 것은 비교적 쉽습니다 (키워드를 추가하기 만하면 됨). 따라서 나중에 (인스턴스 외부의 기능이 필요할 때) 정적이 될 수있는 실제 정적으로 만들려면 할 수 있습니다. 그러나 역 리팩토링, 정적이 될 수있는 인스턴스 메서드로 전환하는 것은 훨씬 더 비쌉니다.

코드 기반이 크면 관념적 순수성보다는 확장의 용이성 측면에서 오류를 일으키는 것이 좋습니다.

따라서 큰 프로젝트의 경우 필요한 경우가 아니면 정적으로 만들지 마십시오. 소규모 프로젝트의 경우 가장 좋아하는 일을하십시오.


나는 것 아니 그것을 만드는 공공 의 정적 멤버 클래스 . 그 이유는 public static으로 만드는 것이 클래스의 유형에 대해 "이 유형은이 동작을 수행하는 방법을 알고있다"뿐만 아니라 "이 동작을 수행하는 것이이 유형의 책임"이라고 말하는 것입니다. 그리고 그 행동은 더 이상 더 큰 유형과 실제 관계가 없습니다.

그렇다고 전혀 정적으로 만들지 않을 것이라는 의미는 아닙니다. 스스로에게 물어보십시오. 새로운 방법이 논리적으로 다른 곳에 속할 수 있습니까? 이에 대해 "예"라고 답할 수 있다면 정적으로 만들고 싶을 것입니다 (또한 이동). 사실이 아니더라도 정적으로 만들 수 있습니다. 표시하지 마십시오 public.

편의상 적어도 표시 할 수 있습니다 internal. 이렇게하면 일반적으로 더 적절한 유형에 쉽게 액세스 할 수없는 경우 메서드를 이동할 필요가 없지만 클래스 사용자에게 공개 인터페이스의 일부로 표시되지 않는 방식으로 필요한 곳에 액세스 할 수 있습니다. .


반드시 그런 것은 아닙니다.

공용 메서드를 정적에서 비 정적으로 이동하는 것은 주요 변경 사항이며 모든 호출자 또는 소비자를 변경해야합니다. 메서드가 인스턴스 메서드처럼 보이지만 인스턴스 멤버를 사용하지 않는 경우 미래 ​​보장의 척도로 인스턴스 메서드로 만드는 것이 좋습니다.


예. "정적 일 수있는"이유는 호출 된 객체의 상태에서 작동하지 않기 때문입니다. 따라서 인스턴스 메서드가 아니라 클래스 메서드입니다. 인스턴스의 데이터에 액세스하지 않고 필요한 작업을 수행 할 수 있다면 정적이어야합니다.


네, 그래야합니다. 클래스가 다른 클래스, 메소드 등과 같은 다른 것들에 어떻게 의존 하는지를 측정하는 다양한 결합 메트릭이 있습니다 . 정적 메소드가 어떤 것도 참조하지 않는다는 것을 확신 할 수 있기 때문에 메소드를 정적으로 만드는 것은 결합 정도를 낮추는 방법입니다. 회원.


나는 그것을 정적으로 표시하면 조금 더 읽기 쉽게 만들 것이라고 생각합니다 ... 그러면 함께 오는 사람은 전체 함수를 읽지 않고도 인스턴스 변수를 참조하지 않는다는 것을 알 것입니다 ...


개인적으로 저는 무국적자의 훌륭한 팬입니다. 메서드가 클래스 상태에 액세스해야합니까? 대답이 '아니오'(아마도 '아니오'이면 정적 메서드로 만드는 것을 고려하지 않을 것입니다), 그래요.

주에 대한 접근은 덜 두통입니다. 다른 클래스에서 필요하지 않은 private 멤버를 숨기는 것이 좋은 생각과 마찬가지로 필요하지 않은 멤버로부터 상태를 숨기는 것이 좋습니다. 액세스 감소는 버그 감소를 의미합니다. 또한 정적 멤버를 스레드로부터 안전하게 유지하는 것이 훨씬 쉽기 때문에 스레딩이 더 쉬워집니다. 런타임에 대한 참조를 전달할 필요가 없기 때문에 성능 고려 사항도있다 정적 메서드의 매개 변수로는.

물론 단점은 이전의 정적 메서드가 어떤 이유로 든 상태에 액세스해야한다는 사실을 발견 한 경우이를 변경해야한다는 것입니다. 이제 나는 이것이 공용 API에 문제가 될 수 있음을 이해하므로 이것이 공용 클래스의 공용 메서드 인 경우 이것의 의미에 대해 생각해야 할 것입니다. 그래도 현실 세계에서 이것이 실제로 문제를 일으킨 상황을 본 적이 없지만 어쩌면 운이 좋을 수도 있습니다.

그래, 꼭 가라.


정적 메서드는 비 정적 메서드보다 빠르므로 가능하면 정적이어야하며 비 정적 상태로 두는 특별한 이유가 없습니다 .


할 수 있다는 이유만으로 무언가를 정적으로 만드는 것은 좋은 생각이 아닙니다. 정적 메서드는 우연이 아니라 디자인으로 인해 정적이어야합니다.

Michael이 말했듯이 나중에 이것을 변경하면 그것을 사용하는 코드가 손상됩니다.

즉, 실제로 설계 상 정적 인 클래스에 대한 개인 유틸리티 함수를 만드는 것처럼 들립니다.


몇 줄을 리팩토링 할 수 있고 결과 메서드가 정적 일 수 있다면 해당 메서드에서 뽑은 줄이 컨테이너 클래스에 전혀 속하지 않는다는 표시 일 수 있으므로 해당 줄로 이동하는 것을 고려해야합니다. 자신의 수업.


실제로 여기에서 캡슐화를 언급하는 사람이 거의 없다는 사실에 놀랐습니다. 인스턴스 메서드는 모든 개인 (인스턴스) 필드, 속성 및 메서드에 자동으로 액세스 할 수 있습니다. 기본 클래스에서 상속 된 모든 보호 된 항목에 추가합니다.

코드를 작성할 때는 가능한 한 적게 노출하고 가능한 한 적게 액세스 할 수 있도록 작성해야합니다.

So yes, it might be important to make your code fast which would happen if you're making your methods static, but usually more important then that is to make your code as incapable of creating bugs as possible too. One way to achieve that is to have your code have access to as little as possible of "private stuff".

This might seem irrelevant at first glance since the OP is obviously talking about refactoring which can not go wrong in this scenario and create any new bugs, however this refactored code must be maintained in the future and modified which makes your code have a bigger "attack surface" in regards to new bugs if it has access to private instance members. So in general I think the conclusion here is that "yes mostly your methods should be static" unless there are any other reasons for not having them static. And this simply because it's "better use of encapsulation and data hiding and creates 'safer' code"...


Personally I would have no choice but to make it static. Resharper issues a warning in this case and our PM has a rule "No warnings from the Resharper".


It depends but generally I do not make those methods static. Code is always changing and perhaps someday I will want to make that function virtual and override it in a subclass. Or perhaps some day it will need to reference instance variables. It will be harder to make those changes if every call site has to be changed.


I suggest that the best way to think about it is this: If you need a class method that needs to be called when no instances of the class are instantioated, or maintains some kind of global state, then static is a good idea. But in general, I suggest you should prefer making members non-static.


You should think about your methods and classes:

  • How are you going to use them?
  • Do you need a lot of acces to them from different levels of your code?
  • Is this a method/class I can use in almost every thinkable project.

If the last two are 'yes', then your method/class should probably be static.

The most used example is probably the Math class. Every major OO language has it and all the methods are static. Because you need to be able to use them anywhere, anytime, without making an instance.

Another good example is the Reverse() method in C#.
This is a static method in the Array class. It reverses the order of your array.

Code:

public static void Reverse(Array array)

It doesn't even return anything, your array is reversed, because all arrays are instances of the Array class.


As long as you make the new method private static it is not a breaking change. In fact, FxCop includes this guidance as one of its rules (http://msdn.microsoft.com/en-us/library/ms245046(VS.80).aspx), with the following information:

After you mark the methods as static, the compiler will emit non-virtual call sites to these members. Emitting non-virtual call sites will prevent a check at runtime for each call that ensures that the current object pointer is non-null. This can result in a measurable performance gain for performance-sensitive code. In some cases, the failure to access the current object instance represents a correctness issue.

That being said, the first comment from David Kean more succinctly summarizes the concerns by saying this is actually more about being correct than about the performance gain:

Although this rule is classified as a performance issue, the performance improvement of making a method static is only around 1%. Rather, it is more a correctness issue that could indicate an either an incomplete or a bug in the member by its failure to use other instance members. Marking a method static (Shared in Visual Basic) makes it clear on its intention not to touch instance state.


I would definitely turn anything I can into static for a different reason:

Static functions, when JIT'd, are called without a "this" parameter. That means, for example, that a 3 parameter non-static function (member method) gets pushed with 4 params on the stack.

The same function compiled as a static function would get called with 3 parameters. This can free up registers for the JIT and conserve stack space...


I'm in the "only make private methods static" camp. Making a public method can introduce coupling that you don't want and may decrease testability: You can't stub a public static method.

If you want to unit test a method that uses a public static method, you end up testing the static method as well, which might not be what you want.


Inherently static methods that are for some reason made non-static are simply annoying. To wit:

I call my bank and ask for my balance.
They ask for my account number.
Fair enough. Instance method.

I call my bank and ask for their mailing address.
They ask for my account number.
WTF? Fail—should have been static method.


I look at it generally from a functional perspective of pure functions. Does it need to be an instance method? If not, you may benefit from forcing the user to pass in the variables and not mangling the current instance's state. (Well, you could still mangle state, but the point is to, by design, not do so.) I generally design instance methods as public members and do my best to make private members static. If necessary (you can then more easily extract them into other classes later.


In those cases, i tend to move the method to a static or utils library, so i don't be mixing the concept of the "object" with the concept of "class"

참고URL : https://stackoverflow.com/questions/731763/should-c-sharp-methods-that-can-be-static-be-static

반응형