如何为班级提供自定义演员支持?

esa*_*sac 91 c# casting

如何提供将我的课程转换为其他类型的支持?例如,如果我有自己的管理a的实现byte[],并且我想让人们将我的类转换为a byte[],这将只返回私有成员,我该怎么做?

通常的做法是让他们也将它转换为字符串,还是应该覆盖ToString()(或两者)?

Cha*_*ana 102

您需要覆盖转换运算符,使用implicit或者explicit取决于您是否希望用户必须强制转换它,或者是否希望它自动发生.一般来说,一个方向总是有效,这就是你使用的地方implicit,另一个方向有时会失败,这就是你使用的地方explicit.

语法是这样的:

public static implicit operator dbInt64(Byte x)
{
    return new dbInt64(x);
}
Run Code Online (Sandbox Code Playgroud)

要么

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

对于您的示例,请从您的自定义类型中说(MyType- > byte[]将始终有效):

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

要么

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;
}
Run Code Online (Sandbox Code Playgroud)


Luk*_*keH 31

您可以使用explicitimplicit关键字在类上声明转换运算符.

作为一般经验法则,您只应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;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用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;
Run Code Online (Sandbox Code Playgroud)

使用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;
Run Code Online (Sandbox Code Playgroud)


Chr*_*ers 7

我更喜欢有一些方法可以做到这一点,而不是重载强制转换运算符。

请参阅显式和隐式 c#,但请注意,从该示例中,使用显式方法,如果您这样做:

string name = "Test";
Role role = (Role) name;
Run Code Online (Sandbox Code Playgroud)

那么一切都很好;但是,如果您使用:

object name = "Test";
Role role = (Role) name;
Run Code Online (Sandbox Code Playgroud)

你现在会得到一个 InvalidCastException 因为字符串不能被转换为 Role,为什么,编译器只在编译时根据它们的编译类型查找隐式/显式转换。在这种情况下,编译器将 name 视为对象而不是字符串,因此不使用 Role 的重载运算符。