[c#] 매개 변수가 일정 할 수 있습니까?

Java와 동등한 C #을 찾고 final있습니다. 존재합니까?

C #에는 다음과 같은 것이 있습니까?

public Foo(final int bar);

위의 예 bar에서은 읽기 전용 변수이며로 변경할 수 없습니다 Foo(). C #에서이 작업을 수행하는 방법이 있습니까?

예를 들어, 어쩌면 내가 함께 작업 할 긴 방법이 x, y그리고 z일부 개체 (INT)로 좌표를. 함수가 어떤 식 으로든 이러한 값을 변경하지 않아 데이터가 손상되지 않는다는 것을 절대적으로 확신하고 싶습니다. 따라서 읽기 전용으로 선언하고 싶습니다.

public Foo(int x, int y, int z) {
     // do stuff
     x++; // oops. This corrupts the data. Can this be caught at compile time?
     // do more stuff, assuming x is still the original value.
}



답변

불행히도 C #에서는 이것을 할 수 없습니다.

const키워드는 지역 변수 및 필드에 사용할 수 있습니다.

readonly키워드는 필드에 사용할 수 있습니다.

참고 : Java 언어는 메소드에 대한 최종 매개 변수도 지원합니다. 이 기능은 C #에 존재하지 않습니다.

에서 http://www.25hoursaday.com/CsharpVsJava.html

편집 (2019/08/13) : 이것이 허용되고 목록에서 가장 높기 때문에 가시성을 위해 이것을 던졌습니다. 이제 in매개 변수 로 가능합니다 . 자세한 내용 아래 답변을 참조하십시오.


답변

이제 C # 버전 7.2에서 가능합니다.

in메소드 서명에 키워드를 사용할 수 있습니다 . MSDN 설명서 .

in키워드는 메소드의 인수를 지정하기 전에 추가해야합니다.

예, C # 7.2의 유효한 메서드 :

public long Add(in long x, in long y)
{
    return x + y;
}

다음은 허용되지 않습니다.

public long Add(in long x, in long y)
{
    x = 10; // It is not allowed to modify an in-argument.
    return x + y;
}

수정을 시도 x하거나 다음 yin같이 표시되어 있기 때문에 다음 오류 가 표시됩니다 .

읽기 전용 변수이므로 ‘in long’변수에 할당 할 수 없습니다.

in의미 로 인수 표시 :

이 메소드는이 매개 변수로 사용되는 인수의 값을 수정하지 않습니다.


답변

여기에 많은 반대표를 얻을 수있는 짧고 달콤한 답변이 있습니다. 게시물과 댓글을 모두 읽지 않았으므로 이전에 제안 된 적이 있다면 용서해주십시오.

매개 변수를 불변으로 노출하는 객체에 전달한 다음 메서드에서 해당 객체를 사용하는 것이 어떻습니까?

나는 이것이 이미 고려 된 매우 명백한 해결 방법이라는 것을 알고 있으며 OP는이 질문을함으로써 이것을 피하려고 노력하고 있지만 그럼에도 불구하고 여기에 있어야한다고 느꼈습니다 …

행운을 빕니다 🙂


답변

대답 : C #에는 C ++와 같은 const 기능이 없습니다.

나는 Bennett Dill에 동의합니다.

const 키워드는 매우 유용합니다. 예제에서 당신은 int를 사용했고 사람들은 당신의 요점을 얻지 못했습니다. 그러나 매개 변수가 해당 함수 내에서 변경할 수없는 사용자 거대하고 복잡한 개체 인 경우 왜? 그것은 const 키워드의 사용입니다 : 매개 변수는 그 메소드에서 중요하지 않기 때문에 그 메소드 안에서 변경할 수 없습니다. Const 키워드는 매우 강력하며 C #에서는 정말 그리워요.


답변

int부분 부터 시작하겠습니다 . int값 유형이며 .Net에서는 실제로 사본을 처리하고 있음을 의미합니다. “이 값의 복사본을 가질 수 있습니다. 이것은 내 복사본이 아니라 귀하의 복사본입니다. 다시는 볼 수 없습니다. 그러나 복사본을 변경할 수는 없습니다.” 이 값을 복사해도 괜찮다는 것은 메서드 호출에서 암시 적입니다. 그렇지 않으면 메서드를 안전하게 호출 할 수 없습니다. 메서드에 원본이 필요한 경우 구현 자에게 맡기고 복사본을 만들어 저장합니다. 메소드에 값을 제공하거나 메소드에 값을 제공하지 마십시오. 그 사이에 엉망진창을하지 마십시오.

참조 유형으로 이동하겠습니다. 이제 약간 혼란스러워집니다. 참조 자체를 변경할 수없는 상수 참조 또는 완전히 잠기고 변경할 수없는 객체를 의미합니까? 전자의 경우 기본적으로 .Net의 참조가 값으로 전달됩니다. 즉, 참조 사본을 얻습니다. 따라서 우리는 본질적으로 값 유형과 동일한 상황을 가지고 있습니다. 구현자가 원본 참조를 필요로하는 경우 자체적으로 유지할 수 있습니다.

그것은 우리에게 상수 (잠금 / 불변) 객체를 남깁니다. 이것은 런타임 관점에서 괜찮아 보일 수 있지만 컴파일러가이를 어떻게 적용합니까? 속성과 메서드 모두 부작용이있을 수 있으므로 기본적으로 읽기 전용 필드 액세스로 제한됩니다. 그러한 개체는 그다지 흥미롭지 않을 것입니다.


답변

읽기 전용 속성 접근 자만있는 클래스의 인터페이스를 만듭니다. 그런 다음 매개 변수가 클래스 자체가 아닌 해당 인터페이스가되도록하십시오. 예:

public interface IExample
{
    int ReadonlyValue { get; }
}

public class Example : IExample
{
    public int Value { get; set; }
    public int ReadonlyValue { get { return this.Value; } }
}


public void Foo(IExample example)
{
    // Now only has access to the get accessors for the properties
}

구조체의 경우 일반 const 래퍼를 만듭니다.

public struct Const<T>
{
    public T Value { get; private set; }

    public Const(T value)
    {
        this.Value = value;
    }
}

public Foo(Const<float> X, Const<float> Y, Const<float> Z)
{
// Can only read these values
}

그래도 주목할 가치가있는 것은 당신이 구조체와 관련하여하려는 일을하고 싶은 것이 이상하다는 것입니다. 그 메서드의 작성자는 그 메서드에서 무슨 일이 일어나고 있는지를 예상해야합니다. 메서드 내에서 값을 수정하기 위해 전달 된 값에 영향을주지 않으므로 작성중인 메서드에서 자신이 행동하는지 확인하는 것이 유일한 관심사입니다. const 및 기타 규칙을 시행하는 것보다 경계와 깨끗한 코드가 핵심이되는 시점이 있습니다.


답변

이런 문제가 자주 발생하는 경우 “헝가리 앱”을 고려해야합니다. 나쁜 종류 와 반대로 좋은 종류 . 이것은 일반적으로 메소드 매개 변수의 상수 성을 표현하려고 시도하지는 않지만 (너무 이례적 임) 식별자 이름 앞에 추가 “c”를 추가하는 것을 막을 수있는 것은 없습니다.

지금 반대 투표 버튼을 누르려는 모든 분들께 다음 주제에 대한 유명 인사들의 의견을 읽어보십시오.