首页 > 解决方案 > C# (CS0039) 如何使用 `as` 运算符定义从字符串到自定义类的转换?

问题描述

是否可以为可以使用“as”转换的类定义(也许)一个运算符?

重点是:

class C
{
   string a;
   string b;

   public C what_here(string s)
   {
      a = s.Substring(0, 2);
      b = s.Substring(3);
   }
}

类的用途:

("something" as C).a;

这给出了:

错误 CS0039:无法通过引用转换、装箱转换、拆箱转换、包装转换或空类型转换将类型“字符串”转换为“C”

PS真实class C的要大得多,关键是如何启用as 操作员,我刚刚习惯了...

标签: c#casting

解决方案


As per the docs for as:

Note that the as operator performs only reference conversions, nullable conversions, and boxing conversions. The as operator can't perform other conversions, such as user-defined conversions, which should instead be performed by using cast expressions.

So you won't be able to use as to invoke an implicit operator.

However, if you're prepared to use implicit or explicit casting:

class C
{
   // Obviously you want to encapsulate these as properties, not fields
   public string a;
   public string b;

   public static implicit operator C(string s)
   {
      var localA = s.Substring(0, 2);
      var localB = s.Substring(3);
      return new C
      {
         a = localA,
         b = localB
      };
   }
}

void Main()
{
    C myC = "AA BBBBBBBB"; // Or explicitly, var myC = (C)"AA BBBBBBBB"
    Console.WriteLine(myC.a);
    Console.WriteLine(myC.b);
}

Output:

AA
BBBBBBBB

But! Don't abuse the conversion operators

As per @Kieran's comment, conversion operators, when used in arbitrary ways, can be really difficult for others to read. It's not particularly intuitive that a string should automagically be converted into your own custom class. IMO the following alternatives are easier to read.

A constructor overload:

var myC = new C("string to parse here");

or an extension method:

var myC = "string to parse here".ToC();  

where ToC will be the same code as the conversion operator, but with the signature public static C ToC(this string s).


推荐阅读