2010-04-06 4 views
2

.NET 'System'DLL을 디스 어셈블하고 변수 클래스 (문자열, 정수, 바이트 등)의 소스 코드를 조사하여 알아낼 수 있는지 확인했습니다. 가치를 가질 수있는 수업을 만드는 방법. "Int32"클래스는 다음을 상속합니다. IComparable, IFormattable, IConvertible, IComparable, IEquatable."int"또는 "string"클래스 만들기

String 및 Int32 클래스는 상속되지 않으므로 상속 된 인터페이스에서 클래스가 값을 보유 할 수있는 것을 파악할 수 없습니다. 내가 원하는 것은 다음과 같습니다.

public class MyVariable : //inherits here 
{ 
    //Code in here that allows it to get/set the value 
} 

public static class Main(string[] args) 
{ 
    MyVariable a = "This is my own custom variable!"; 
    MyVariable b = 2976; 

    if(a == "Hello") { } 
    if(b = 10) { } 
    Console.WriteLine(a.ToString()); 
    Console.WriteLine(a.ToString()); 
} 
+2

이 컴파일을 할 수는 있지만 ... 왜? –

+1

두 번째 if는'='(아마도'b == 10 '이어야 함) –

+1

위 코드의 12 번째 줄에서'if (b == 10) {}'대신'if (b = 10) {}'? –

답변

7

당신은 그 overloading operators으로 작업을 수행 할 수 있습니다

여기에 완벽한 예입니다. MSDN에 대한 자습서가 있습니다.

의 당신이 (하스켈의 Either 같은) 문자열이나 int 형이 될 수있는 유형을 원하는 가정 해 봅시다 :

public sealed class StringOrInt32 
{ 
    private string stringValue; 
    private int int32Value; 
    private bool isString; 

    public bool IsString { get { return isString; } } 
    public bool IsInt32 { get { return !isString; } } 

    public string StringValue 
    { 
     get 
     { 
      if(!isString) throw new InvalidOperationException(); 
      return stringValue; 
     } 
    } 

    public int Int32Value 
    { 
     get 
     { 
      if(isString) throw new InvalidOperationException(); 
      return int32Value; 
     } 
    } 

    public StringOrInt32(string value) 
    { 
     isString = true; 
     stringValue = value; 
    } 

    public StringOrInt32(int value) 
    { 
     isString = false; 
     int32Value = value; 
    } 

    // Allows writing this: 
    // StringOrInt32 foo = "Hello world!"; 
    public static implicit operator StringOrInt32(string value) 
    { 
     return new MyVariable(value); 
    } 

    // Allows writing this: 
    // StringOrInt32 foo = 42; 
    public static implicit operator StringOrInt32(int value) 
    { 
     return new MyVariable(value); 
    } 

    // Allows writing this: 
    // StringOrInt32 foo = "Hello world!; 
    // string bar = (string)foo; 
    // Though foo.StringValue directly would be better 
    public static explicit operator string(StringOrInt32 value) 
    { 
     return value.StringValule; 
    } 

    // Allows writing this: 
    // StringOrInt32 foo = 42; 
    // int bar = (int)foo; 
    // Though foo.Int32Value directly would be better 
    public static explicit operator int(StringOrInt32 value) 
    { 
     return value.Int32Value; 
    } 

    public static bool operator==(StringOrInt32 left, StringOrInt32 right) 
    { 
     if(left.IsString != right.IsString) 
      return false; 
     if(left.IsString) 
      return left.StringValue == right.StringValue; 
     else 
      return left.Int32Value == right.Int32Value; 
    } 

    public static bool operator!=(StringOrInt32 left, StringOrInt32 right) 
    { 
     return !(left == right) 
    } 

    // Don't forget to override object.Equals(), object.GetHashCode(), 
    // and consider implementing IEquatable<StringOrInt32> 
    // Also, null checks, etc 
} 
+0

감사! 다른 답변들 중 하나와 마찬가지로, 이것이 제가 찾고있는 것과 정확히 같습니다. – afollestad

1

"int"및 "string"은 기본 제공 유형입니다. 식별 가능한 필드가없는 것과 같은 것을 만들 수 없습니다. 그러나 내장 유형과 거의 비슷하게 보이고 작동하는 것을 만들 수 있습니다.

가장 좋은 예는 Nullable<T>입니다. 이 모든 값 유형의 널 (NULL) 버전을 제공하며이 내장 된 것처럼 할당 할 수 있습니다 :

int? x = 0; 
int? y = null; 

Nullable<T>가 명시 적 및 암시 적 캐스트를 우선입니다 작동하는 방법. 이렇게하면 사용자 정의 Nullable<int>에 int와 같은 내장 유형을 할당하고 Nullable<int>.op_Implicit의 코드는 변환을 투명하게 처리 할 수 ​​있습니다.

public struct MyVariable 
{ 
    private int _intValue; 
    private string _stringValue; 

    public override bool Equals(object obj) 
    { 
     if (!(obj is MyVariable)) 
     { 
      return false; 
     } 
     var y = (MyVariable) obj; 
     return _stringValue == y._stringValue && _intValue == y._intValue; 
    } 

    public override int GetHashCode() 
    { 
     return (_stringValue ?? _intValue.ToString()).GetHashCode(); 
    } 

    public override string ToString() 
    { 
     return _stringValue ?? _intValue.ToString(); 
    } 

    public static implicit operator MyVariable(string value) 
    { 
     return new MyVariable { _stringValue = value }; 
    } 

    public static implicit operator MyVariable(int value) 
    { 
     return new MyVariable { _intValue = value }; 
    } 

    public static bool operator==(MyVariable variable, string value) 
    { 
     return variable._stringValue == value; 
    } 

    public static bool operator ==(MyVariable variable, int value) 
    { 
     return variable._intValue == value; 
    } 

    public static bool operator !=(MyVariable variable, string value) 
    { 
     return variable._stringValue == value; 
    } 

    public static bool operator !=(MyVariable variable, int value) 
    { 
     return variable._intValue == value; 
    } 

    public static void Test() 
    { 
     MyVariable a = "This is my own custom variable!"; 
     MyVariable b = 2976; 

     if (a == "Hello") { } 
     if (b == 10) { } 
     Console.WriteLine(a.ToString()); 
     Console.WriteLine(a.ToString()); 
    } 
} 
+0

Nullable에는 실제로 C# : emitted 연산자에서 에뮬레이트 할 수없는 캐스트 뒤에 몇 가지 추가 마법이 있습니다. –

+0

감사! 이것은 내가 찾고 있었던 바로 그 것이다. – afollestad

3

내장 된 C#에서 유형 "특별히"그에서 처리되는 리터럴 값 1234 코드에서 System.Int32 형식으로 정의되고 리터럴 값 "some string"은 System.String 형식으로 정의됩니다.

그래서 원하는 종류의 코드를 지원하려면 int와 string (그리고 무엇이든간에)을 사용자의 유형으로 변환 할 수있는 변환 연산자를 제공해야합니다. MSDN의 conversion operators 항목을 살펴보십시오.

1

일반적으로 새로운 유형의 데이터를 저장하려면 새 유형을 만들고 싶습니다. 위의 예에서 MyVariable을 사용하여 문자열을 저장합니다. 문자열 유형이 이미 잘 수행되고 있습니다.

위에서 시작했습니다 당신이 당신이 그것을 할 것 패키지 주위에 보낼 수있는 쉬운 이러한 문자열과 INT의 조합 같은 데이터의 다른 유형을 저장하려면 :

public class MyVariable 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
} 

을 다음 :

MyVariable personOne = new MyVariable { Name = "John", Age = 34 }; 
MyVariable personTwo = new MyVariable { Name = "Joe", Age = 312 }; 
같은에서 IComparable 및 IFormattable은 예를 들어에서 IComparable가 다른 인스턴스 자체를 비교 할 수로 정렬 된 목록에 전달 될 수있는 특정 방법으로 사용할 수의 새로운 유형을 허용하는

인터페이스 '순위'적절하게 .