다음을 통해 공유


사용자 정의 연산자 선언에서 오류 및 경고 해결

이 문서에서는 다음 컴파일러 오류를 다룹니다.

  • CS0056: 접근성이 일관되지 않음: 반환 형식 'type'이 연산자 'operator'보다 접근성이 떨어집니다.
  • CS0057: 접근성이 일관되지 않음: 매개 변수 형식 'type'이 연산자 'operator'보다 접근성이 떨어집니다.
  • CS0215: True 또는 False 연산자의 반환 형식은 bool이어야 합니다.
  • CS0216: 연산자 '연산자'를 정의하려면 일치하는 연산자 'missing_operator'도 정의해야 합니다.
  • CS0217: 단락 연산자로 적용하려면 사용자 정의 논리 연산자('operator')가 2 매개 변수의 형식과 동일한 반환 형식을 가져야 합니다.
  • CS0218: 형식('type')에는 연산자 true 및 연산자 false의 선언이 포함되어야 합니다.
  • CS0448: 또는 ++ 연산자의 반환 형식 -- 은 포함하는 형식이거나 포함하는 형식에서 파생되어야 합니다.
  • CS0552: '변환 루틴': 인터페이스로/에서 사용자 정의 변환
  • CS0553: '변환 루틴': 기본 클래스로/에서 사용자 정의 변환
  • CS0554: '변환 루틴': 파생 클래스로/에서 사용자 정의 변환
  • CS0555: 사용자 정의 연산자는 둘러싸고 있는 형식의 객체를 가져와 같은 형식의 객체로 변환할 수 없습니다.
  • CS0556: 사용자 정의 변환은 포함 형식으로 또는 포함 형식에서 변환해야 합니다.
  • CS0557: 형식 내 중복된 사용자 정의 변환
  • CS0558: 사용자 정의 연산자는 정적 및 공용으로 선언되어야 합니다.
  • CS0559: ++ 또는 -- 연산자의 매개 변수 형식은 포함하는 형식이어야 합니다.
  • CS0562: 단항 연산자의 매개 변수는 포함하는 형식이어야 합니다.
  • CS0563: 이진 연산자의 매개 변수 중 하나는 포함하는 형식이어야 합니다.
  • CS0564: 오버로드된 시프트 연산자의 첫 번째 피연산자는 포함하는 형식과 동일한 형식이어야 하며 두 번째 피연산자의 형식은 int여야 합니다.
  • CS0567: 인터페이스에 연산자를 포함할 수 없음
  • CS0590: 사용자 정의 연산자는 void를 반환할 수 없습니다.
  • CS0660: operator ==.
  • CS0661: 형식은 operator == 또는 operator !=를 정의하지만 Object.GetHashCode()를 재정의하지 않습니다.
  • CS0715: 정적 클래스는 사용자 정의 연산자를 포함할 수 없습니다.
  • CS1037: 오버로드 가능한 연산자가 필요합니다.
  • CS1553: 선언이 유효하지 않습니다. '수식자 연산자 <dest-type> (...' 대신 사용하십시오.
  • CS8930: 사용자 정의 연산자의 명시적 구현은 정적이어야 합니다.
  • CS8931: 형식의 인터페이스 멤버를 구현하려면 명시적 구현을 public으로 선언해야 합니다.
  • CS9023: 연산자를 확인 가능하도록 만들 수 없습니다.
  • CS9024: 연산자를 선택 취소할 수 없습니다.
  • CS9025: 연산자는 일치하는 확인되지 않은 버전도 선언해야 합니다.
  • CS9308: 사용자 정의 연산자는 public으로 선언되어야 합니다.
  • CS9310: 이 연산자의 반환 형식은 void여야 합니다.
  • CS9311: 형식은 인터페이스 멤버를 구현하지 않습니다. 형식 중 하나가 연산자가 아니므로 멤버를 구현할 수 없습니다.
  • CS9312: 형식은 상속된 멤버 중 하나가 연산자가 아니므로 재정의할 수 없습니다.
  • CS9313: 오버로드된 복합 할당 연산자는 하나의 매개 변수를 사용합니다.
  • CS9340: 연산자는 피연산자에 적용할 수 없습니다. 적용할 수 없는 가장 가까운 후보가 표시됩니다.
  • CS9341: 연산자를 피연산자에 적용할 수 없습니다. 적용할 수 없는 가장 유사한 후보가 표시됩니다.
  • CS9342: 다음 멤버 간에 연산자 선택이 모호합니다.

운영자 서명 요구 사항

  • CS0448: 또는 ++ 연산자의 반환 형식 -- 은 포함하는 형식이거나 포함하는 형식에서 파생되어야 합니다.
  • CS0559: ++ 또는 -- 연산자의 매개 변수 형식은 포함하는 형식이어야 합니다.
  • CS0562: 단항 연산자의 매개 변수는 포함하는 형식이어야 합니다.
  • CS0563: 이진 연산자의 매개 변수 중 하나는 포함하는 형식이어야 합니다.
  • CS0564: 오버로드된 시프트 연산자의 첫 번째 피연산자는 포함하는 형식과 동일한 형식이어야 하며 두 번째 피연산자의 형식은 int여야 합니다.
  • CS0567: 인터페이스에는 연산자를 포함할 수 없습니다.
  • CS0590: 사용자 정의 연산자는 void를 반환할 수 없습니다.
  • CS9310: 이 연산자의 반환 형식은 void여야 합니다.
  • CS9340: 연산자는 피연산자에 적용할 수 없습니다. 적용할 수 없는 가장 가까운 후보가 표시됩니다.
  • CS9341: 연산자를 피연산자에 적용할 수 없습니다. 적용할 수 없는 가장 가까운 후보가 표시됩니다.
  • CS9342: 다음 멤버 간에 연산자 결정이 모호합니다.

올바른 서명을 사용하여 연산자를 선언하려면 특정 연산자 유형에 대해 다음 요구 사항을 따릅니다. 자세한 내용은 연산자 오버로드를 참조하세요.

  • 포함된 형식(또는 파생 형식)을 ++-- 연산자(CS0448)에서 반환합니다.
  • 포함 형식을 매개 변수 ++-- 연산자(CS0559)로 사용합니다.
  • 포함된 형식을 단항 연산자의 매개 변수로 사용합니다(CS0562).
  • 포함하는 형식을 이진 연산자(CS0563)에 하나 이상의 매개 변수로 포함합니다.
  • 포함하는 형식을 첫 번째 매개 변수 int 로 사용하고 시프트 연산자(CS0564)의 두 번째 매개 변수로 사용합니다.
  • 인터페이스에서 연산자를 선언하지 마세요(CS0567). 인터페이스는 연산자 구현을 포함할 수 없습니다.
  • 반환이 필요한 특정 연산자를 제외하고 대부분의 연산자(void)에서 void가 아닌 형식을 반환합니다(CS9310).
  • 해결 실패를 방지하기 위해 올바른 매개 변수 형식을 허용하는 연산자 오버로드를 제공합니다(CS9340, CS9341).
  • 명시적 캐스트를 사용하거나 보다 구체적인 오버로드(CS9342)를 제공하여 연산자 호출을 명확하게 합니다.

중요합니다

정적 이진 연산자와 해당 인스턴스 복합 할당 연산자의 서명 요구 사항은 다릅니다. 서명이 원하는 선언과 일치하는지 확인합니다.

다음 예제에서는 서명 오류를 보여 줍니다.

class C1
{
    public static int operator ++(C1 c) => 0;   // CS0448
    public static C1 operator --(C1 c) => null;   // OK
}
public class C2
{
    public static implicit operator int(C2 x) => 0;
    public static implicit operator C2(int x) => new C2();
    public static int operator ++(int aa) => 0;  // CS0559
}
public class C3
{
    public static implicit operator int(C3 x) => 0;
    public static implicit operator C3(int x) => null;
    public static C3 operator +(int aa) => 0;   // CS0562
}
public class C4
{
    public static implicit operator int(C4 x) => 0;
    public static implicit operator C4(int x) => null;
    public static int operator +(int aa, int bb) => 0;   // CS0563
}
class C5
{
    // To correct, change second operand to int, like so:
    // public static int operator << (C c1, int c2)
    public static int operator <<(C5 c1, C5 c2) => 0; // CS0564
}
interface IA
{
    int operator +(int aa, int bb);   // CS0567
}
public class C6
{
    public static void operator +(C6 A1, C6 A2) { }  // CS0590
}

운영자 선언 요구 사항

  • CS0558: 사용자 정의 연산자는 정적 및 공용으로 선언되어야 합니다.
  • CS0715: 정적 클래스는 사용자 정의 연산자를 포함할 수 없습니다.
  • CS1037: 오버로드 가능한 연산자가 필요합니다.
  • CS1553: 선언이 유효하지 않습니다. 대신 '수정 연산자 <데스트 타입> (...'를 사용하십시오.
  • CS8930: 사용자 정의 연산자의 명시적 구현은 정적이어야 합니다.
  • CS8931: 형식의 인터페이스 멤버를 구현하려면 명시적 구현을 public으로 선언해야 합니다.
  • CS9308: 사용자 정의 연산자는 public으로 선언되어야 합니다.

연산자를 올바르게 선언하려면 한정자 및 포함 형식에 대해 다음 요구 사항을 따릅니다. 자세한 내용은 연산자 오버로드사용자 정의 변환 연산자를 참조하세요.

  • 모두 staticpublic 한정자를 사용하여 연산자를 선언합니다 (CS0558, CS9308).
  • 정적 클래스에서 연산자를 선언하지 마세요(CS0715). 일반 클래스 또는 구조체를 사용합니다.
  • 유효한 오버로드 가능한 연산자 기호를 사용합니다(CS1037).
  • 변환 연산 public static implicit/explicit operator <dest-type>(<source-type> parameter) 자(CS1553)에 대한 올바른 구문을 따릅니다.
  • 연산자의 명시적 인터페이스 구현이 (static) 및 (public)인지 확인합니다.

다음 예제에서는 선언 오류를 보여 줍니다.

public class C
{
    static implicit operator int(C aa) => 0;   // CS0558, add public
}
public static class C1
{
    public static int operator +(C1 c) => 0;  // CS0715
}
class C2
{
    public static int implicit operator (C2 f) => 6;   // CS1553
}

일관되지 않은 접근성

  • CS0056: 일관성 없는 접근성: 반환 형식 'type'은 연산자 'operator'보다 접근성이 떨어집니다.
  • CS0057: 접근성이 일치하지 않습니다. 매개 변수 형식 'type'은 연산자 'operator'보다 접근성이 떨어집니다.

연산자 선언에서 일관된 접근성을 보장하려면 공용 연산자에 사용되는 모든 형식을 공개적으로 액세스할 수 있도록 합니다. 자세한 내용은 엑세스 수정자를 참조하세요.

  • 반환 형식에 연산자(CS0056)와 적어도 동일한 접근성이 있는지 확인합니다.
  • 매개 변수 형식이 연산자(CS0057)와 적어도 동일한 접근성을 갖도록 합니다.

연산자를 public 선언할 때 매개 변수 또는 반환 값으로 사용되는 모든 형식도 공개적으로 액세스할 수 있어야 합니다.

다음 예제에서는 접근성 오류를 보여 줍니다.

class C { }

public class C2
{
    public static implicit operator C(C2 a) => new C();   // CS0056
}

public class C3
{
    public static implicit operator C3(C c) => new C3();   // CS0057
}

사용자 정의 변환 제한

  • CS0552: 인터페이스로/에서 사용자 정의 변환.
  • CS0553: 기본 클래스로/에서 사용자 정의 변환
  • CS0554: 파생 클래스에 대한 사용자 정의 변환입니다.
  • CS0555: 사용자 정의 연산자는 바깥쪽 형식의 개체를 가져와 바깥쪽 형식의 개체로 변환할 수 없습니다.
  • CS0556: 사용자 정의 변환은 포함하는 형식으 로 또는 포함하는 형식으로 변환해야 합니다.
  • CS0557: 형식 내 중복된 사용자 정의 변환입니다.

유효한 사용자 정의 변환 연산자를 만들려면 다음 제한 사항을 따릅니다. 자세한 내용은 사용자 정의 변환 연산자를 참조하세요.

  • 인터페이스로의 변환이나 인터페이스로부터의 변환을 정의하지 마세요(CS0552). 대신 명시적 인터페이스 구현을 사용합니다.
  • 기본 클래스(CS0553)에 대한 변환을 정의하지 마세요. 변환은 상속을 통해 이미 존재합니다.
  • 파생 클래스(CS0554)에 대한 변환을 정의하지 마세요. 변환은 상속을 통해 이미 존재합니다.
  • 바깥쪽 형식에서 자체(CS0555)로의 변환을 정의하지 마세요. 이 변환은 암시적입니다.
  • 변환에서 하나 이상의 형식이 바깥쪽 형식(CS0556)인지 확인합니다. 두 외부 형식 간의 변환은 정의할 수 없습니다.
  • 중복 변환을 정의하지 마세요(CS0557). 각 변환 연산자는 고유해야 합니다.

다음 예제에서는 변환 제한 오류를 보여 줍니다.

public interface I
{
}
public class C
{
    public static implicit operator I(C aa) => default;// CS0552
}

public class B
{
}
public class D : B
{
    public static implicit operator B(D aa) => new B();// CS0553
}

public class B2
{
    // delete the conversion routine to resolve CS0554
    public static implicit operator B2(D2 d) => new B2();// CS0554
}
public class D2 : B2 { }

public class C2
{
    public static implicit operator C2(C2 aa) => new C2();   // CS0555
}

public class C3
{
    public static implicit operator int(byte aa) => 0;   // CS0556
}

public class C4
{
    public static implicit operator int(C4 aa) => 0;

    // CS0557, delete duplicate
    public static explicit operator int(C4 aa) => 0;
}

불린 및 단락 회로 연산자

  • CS0215: true 또는 false 연산자의 반환 형식은 bool이어야 합니다.
  • CS0216: 연산자를 정의하려면 일치하는 연산자도 정의해야 합니다.
  • CS0217: 단락 연산자로 적용하려면 사용자 정의 논리 연산자가 2개 매개 변수의 형식과 동일한 반환 형식을 가져야 합니다.
  • CS0218: 형식에는 연산자 true 및 연산자 false 선언이 포함되어야 합니다.

논리 연산자를 올바르게 정의하려면 다음 페어링 및 서명 요구 사항을 따릅니다. 자세한 내용은 true 및 false 연산자, 부울 논리 연산자 및 사용자 정의 조건부 논리 연산자를 참조하세요.

  • 에서 반환 (CS0215).
  • 필요한 쌍을 이루는 연산자 정의(CS0216):
    • operator ==operator !=이 필요합니다.
    • operator <operator >가 필요합니다
    • operator <=operator >=를 필요로 합니다.
    • operator trueoperator false을 필요로 합니다.
  • 반환 형식을 사용자 지정 형식과 함께 작동하는 단락 연산자(&|)의 매개 변수 형식과 매칭하십시오 (CS0217).
  • 사용자 지정 형식을 &&||와 같은 부울 컨텍스트에서 사용할 때, operator trueoperator false 둘 다 구현하십시오 (CS0218).

다음 예제에서는 논리 연산자 오류를 보여 줍니다.

class C
{
    public static int operator true(C c) => 0;   // CS0215
    public static int operator false(C c) => 0; // CS0215
}

class C2
{
    public static bool operator ==(C2 left, C2 right) => left.Equals(right);   // CS0216

    public override bool Equals(object? o) => base.Equals(o);
    public override int GetHashCode() => base.GetHashCode();
}

public class C3
{
    public static bool operator true(C3 f) => false;
    public static bool operator false(C3 f) => true;
    public static implicit operator int(C3 x) => 0;
    public static int operator &(C3 f1, C3 f2) => new C3();  // CS0217
}

public class C4
{
    public static implicit operator int(C4 x) => 0;
    public static C4 operator &(C4 f1, C4 f2) => new C4();

    public static void Main()
    {
        C4 f = new C4();
        int i = f && f;   // CS0218, requires operators true and false
    }
}

확인된 연산자

  • CS9023: 연산자를 검사 모드로 만들 수 없습니다.
  • CS9024: 연산자를 선택 취소할 수 없습니다.
  • CS9025: 확인된 연산자를 사용하려면 일치하는 확인되지 않은 버전도 선언해야 합니다.

확인된 연산자를 올바르게 사용하려면 다음 요구 사항을 따릅니다. 자세한 내용은 산술 연산자사용자 정의 확인 연산자를 참조하세요.

  • 지원되는 산술 연산자인 +, -, *, /, ++, -- 및 명시적 변환(CS9023, CS9024)에 checked 또는 unchecked 키워드를 만 적용하세요.
  • 확인된 연산자(CS9025)를 선언할 때 선택 및 선택되지 않은 버전을 모두 제공합니다. 컴파일러는 서로 다른 컨텍스트를 처리해야 합니다.

인터페이스 및 상속 요구 사항

  • CS9311: 형식은 인터페이스 멤버를 구현하지 않습니다. 형식 중 하나가 연산자가 아니므로 멤버를 구현할 수 없습니다.
  • CS9312: 형식은 상속된 멤버 중 하나가 연산자가 아니므로 재정의할 수 없습니다.
  • CS9313: 오버로드된 복합 할당 연산자는 하나의 매개 변수를 사용합니다.

연산자를 올바르게 구현하고 재정의하려면 다음 요구 사항을 따릅니다. 자세한 내용은 연산자 오버로드인터페이스를 참조하세요.

  • 연산자 선언이 인터페이스 멤버의 서명 및 형식과 일치하는지 확인합니다(CS9311). 연산자는 비 연산자 멤버를 구현할 수 없습니다.
  • 재정의되는 상속된 멤버도 연산자인지 확인합니다(CS9312). 연산자는 비 연산자 멤버를 재정의할 수 없습니다.
  • 하나의 매개 변수를 사용하여 복합 할당 연산자를 선언합니다(CS9313). 왼쪽 피연산자는 암시적으로 this이다.

같음 연산자

  • CS0660: Type은 연산자 == 또는 연산자 !=를 정의하지만 Object.Equals(object o)를 재정의하지는 않습니다.
  • CS0661: Type은 연산자 == 또는 연산자 !=를 정의하지만 Object.GetHashCode()를 재정의하지는 않습니다.

같음을 올바르게 구현하려면 사용자 지정 같음 연산자를 정의할 때 해당 Object 메서드를 재정의합니다. 자세한 내용은 형식의 값 같음을 정의하는 방법같음 연산자를 참조하세요.

  • operator == 또는 operator !=를 정의할 때 Object.Equals를 재정의하세요 (CS0660).
  • Object.GetHashCode를 정의하거나 operator == 또는 operator !=를 정의할 때 CS0661를 재정의합니다.

이러한 메서드를 재정의하면 다양한 API 및 컬렉션 형식에서 일관된 같음 동작이 보장됩니다.