programing tip

내 수업에 대한 사용자 지정 캐스트 지원을 제공하려면 어떻게해야합니까?

itbloger 2020. 9. 10. 07:28
반응형

내 수업에 대한 사용자 지정 캐스트 지원을 제공하려면 어떻게해야합니까?


내 클래스를 다른 유형으로 캐스팅하기위한 지원을 제공하려면 어떻게해야합니까? 예를 들어,을 관리하는 자체 구현이 byte[]있고 사람들이 내 클래스를으로 캐스트 할 수 있도록 byte[]하여 private 멤버를 반환하려면 어떻게해야합니까?

그들이 이것을 문자열로 캐스트하도록하는 것이 일반적인 관행입니까, 아니면 그냥 오버라이드 ToString()(또는 둘 다)해야합니까?


변환 연산자를 재정의해야 합니다. 사용자가 캐스트해야하는지 여부 또는 자동으로 발생하도록 하려는지 여부에 따라 implicit또는 둘 중 하나를 사용합니다 explicit. 일반적으로 한 방향은 항상 작동합니다. 여기서는 사용 implicit하고 다른 방향은 때때로 실패 할 수 있습니다 explicit.

구문은 다음과 같습니다.

public static implicit operator dbInt64(Byte x)
{
    return new dbInt64(x);
}

또는

public static explicit operator Int64(dbInt64 x)
{
    if (!x.defined)
        throw new DataValueNullException();
    return x.iVal;
}

예를 들어 사용자 정의 유형에서 말하십시오 ( MyType-> byte[]항상 작동합니다).

public static implicit operator byte[] (MyType x)
{
    byte[] ba = // put code here to convert x into a byte[]
    return ba;
}

또는

public static explicit operator MyType(byte[] x)
{
    if (!CanConvert)
        throw new DataValueNullException();

    // Factory to convert byte[] x into MyType
    MyType mt = MyType.Factory(x);
    return mt;
}

explicit또는 implicit키워드를 사용하여 클래스에서 변환 연산자를 선언 할 수 있습니다 .

일반적으로 implicit변환이 실패 할 수없는 경우 에만 변환 연산자를 제공해야합니다 . explicit변환이 실패 할 수있는 경우 변환 연산자를 사용하십시오 .

public class MyClass
{
    private byte[] _bytes;

    // change explicit to implicit depending on what you need
    public static explicit operator MyClass(byte[] b)
    {
        MyClass m = new MyClass();
        m._bytes = b;
        return m;
    }

    // change explicit to implicit depending on what you need
    public static explicit operator byte[](MyClass m)
    {
        return m._bytes;
    }
}

사용 explicit은 클래스의 사용자가 명시 적 변환을 수행해야 함을 의미합니다.

byte[] foo = new byte[] { 1, 2, 3, 4, 5 };
// explicitly convert foo into an instance of MyClass...
MyClass bar = (MyClass)foo;
// explicitly convert bar into a new byte[] array...
byte[] baz = (byte[])bar;

사용 implicit은 클래스의 사용자가 명시 적 변환을 수행 할 필요가 없음을 의미하며 모든 것이 투명하게 발생합니다.

byte[] foo = new byte[] { 1, 2, 3, 4, 5 };
// imlpicitly convert foo into an instance of MyClass...
MyClass bar = foo;
// implicitly convert bar into a new byte[] array...
byte[] baz = bar;

캐스트 연산자를 오버로드하는 것보다 그렇게하는 방법을 선호합니다.

See explicit and implicit c# but note that from that example, using the explicit method, if you do:

string name = "Test";
Role role = (Role) name;

Then everything is fine; however, if you use:

object name = "Test";
Role role = (Role) name;

You will now get an InvalidCastException because string cannot be cast to Role, why, the compiler only looks for implicit/explicit casts at compile time based upon their compiled type. In this case the compiler sees name as an object rather than string, and thus doesn't use Role's overloaded operator.


For custom cast support you need to provide cast operators (explicit or implicit). The following example of EncodedString class is a simplistic implementation of string with custom encoding (may be useful if you have to process huge-huge strings and run into memory consumption problems because .Net strings are Unicode - every character takes 2 bytes of memory - and EncodedString can take 1 byte per char).

EncodedString can be converted to byte[] and to System.String. Comments in code shed some light and also explain an example when implicit conversion can be dangerous.

Usually you need a very good reason to declare any conversion operators in the first place because.

Further reading is available on MSDN.

class Program
{
    class EncodedString
    {
        readonly byte[] _data;
        public readonly Encoding Encoding;

        public EncodedString(byte[] data, Encoding encoding)
        {
            _data = data;
            Encoding = encoding;
        }

        public static EncodedString FromString(string str, Encoding encoding)
        {
            return new EncodedString(encoding.GetBytes(str), encoding);
        }

        // Will make assumption about encoding - should be marked as explicit (in fact, I wouldn't recommend having this conversion at all!)
        public static explicit operator EncodedString(byte[] data)
        {
            return new EncodedString(data, Encoding.Default);
        }

        // Enough information for conversion - can make it implicit
        public static implicit operator byte[](EncodedString obj)
        {
            return obj._data;
        }

        // Strings in .Net are unicode so we make no assumptions here - implicit
        public static implicit operator EncodedString(string text)
        {
            var encoding = Encoding.Unicode;
            return new EncodedString(encoding.GetBytes(text), encoding);
        }

        // We have all the information for conversion here - implicit is OK
        public static implicit operator string(EncodedString obj)
        {
            return obj.Encoding.GetString(obj._data);
        }
    }

    static void Print(EncodedString format, params object[] args)
    {
        // Implicit conversion EncodedString --> string
        Console.WriteLine(format, args);
    }

    static void Main(string[] args)
    {
        // Text containing russian letters - needs care with Encoding!
        var text = "Привет, {0}!";

        // Implicit conversion string --> EncodedString
        Print(text, "world");

        // Create EncodedString from System.String but use UTF8 which takes 1 byte per char for simple English text
        var encodedStr = EncodedString.FromString(text, Encoding.UTF8);
        var fileName = Path.GetTempFileName();

        // Implicit conversion EncodedString --> byte[]
        File.WriteAllBytes(fileName, encodedStr);

        // Explicit conversion byte[] --> EncodedString
        // Prints *wrong* text because default encoding in conversion does not match actual encoding of the string
        // That's the reason I don't recommend to have this conversion!
        Print((EncodedString)File.ReadAllBytes(fileName), "StackOverflow.com");

        // Not a conversion at all. EncodingString is instantiated explicitly
        // Prints *correct* text because encoding is specified explicitly
        Print(new EncodedString(File.ReadAllBytes(fileName), Encoding.UTF8), "StackOverflow.com");

        Console.WriteLine("Press ENTER to finish");
        Console.ReadLine();
    }
}

참고URL : https://stackoverflow.com/questions/1407689/how-do-i-provide-custom-cast-support-for-my-class

반응형