【问题标题】:Casting from one user defined class to another with return problems. (C#) [duplicate]从一个用户定义的类转换到另一个有返回问题的类。 (C#) [重复]
【发布时间】:2021-04-29 20:00:14
【问题描述】:

我是 C# 新手,这并没有多大意义。 我正在将一个非常简单的名为 User 的类转换为另一个相当简单的名为 InputCapsule 的类。 我遇到的问题是返回输入胶囊时,VS 会说以下内容。

用户定义的转换必须与封闭类型相互转换。

我很困惑,因为我返回了正确的类型。 我的参考代码:

(名称、电子邮件和密码是属性,如果这会改变事情的话。)

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Hello
{
    public class InputCapsule<T>
    {
        public static explicit operator InputCapsule<string>(User v)
        {
            InputCapsule<string> @out = new InputCapsule<string>();
            @out.inputs.Add(v.Name);
            @out.inputs.Add(v.Email);
            @out.inputs.Add(v.Pass);
            return @out;
        }
        public List<T> inputs;
    }
} 

【问题讨论】:

  • 您的方法正在转换为InputCapsule&lt;string&gt; 而不是InputCapsule&lt;T&gt;。封闭类型是public class InputCapsule&lt;T&gt;
  • “我返回了正确的类型”——不,你不是。错误消息准确地解释了您的代码有什么问题。

标签: c# casting


【解决方案1】:

这里对于“cast in (current type)”(如果此表达式存在,我不知道),您不能使用封闭构造的泛型类型作为显式运算符的“名称”的泛型类型参数,因为方法定义是针对开放类型的(对不起,如果我没有使用好词)。

在这里你没有使用通用的“方法”,你正在定义它,因为它需要一个不同于InputCapsule&lt;&gt; 类型的参数(参见@Sweeper 的回答,我将称之为“排除(当前类型)")。

因此这里的泛型类型参数T 必须与InputCapsule&lt;T&gt; 中的类本身相同。

因此,您接下来可以检查 T 是否是方法主体中的字符串,以允许或禁止(抛出异常)强制转换,或执行其他相关操作。

你可以例如写:

public class InputCapsule<T>
{
  public static explicit operator InputCapsule<T>(User v)
  {
    if ( typeof(T) == typeof(string) )
    {
      InputCapsule<string> instance = new InputCapsule<string>();
      instance.inputs.Add(v.Name);
      instance.inputs.Add(v.Email);
      instance.inputs.Add(v.Pass);
      return (InputCapsule<T>)(object)instance;
    }
    else
      throw new InvalidCastException();
  }
  public List<T> inputs = new List<T>();
}

public class User
{
  public string Name;
  public string Email;
  public string Pass;
}

为了返回好的类型,我们使用装箱和拆箱。

所以你可以实现任何你需要的类型转换:

if ( typeof(T) == typeof(string) )
{
}
else
if ( typeof(T) == typeof(int) )
{
}
else
if ( typeof(T) == typeof(MyClass) )
{
}
else
  throw new InvalidCastException();

同样使用新的开关模式匹配...

测试

  var user = new User { Name = "name", Email = "mail@mail.com", Pass = "pwd" };

  var inputcapsule = (InputCapsule<string>)user;

  Console.WriteLine(string.Join(Environment.NewLine, inputcapsule.inputs));

输出

name
mail@mail.com
pwd

User-defined conversion operators (C# reference)

What exactly is an "open generic type" in .NET?

Generics open and closed constructed types

Open and Closed Generic Types in C#

【讨论】:

    【解决方案2】:

    转换运算符的源类型或目标类型必须与封闭类/结构的类型相同。在这里,封闭类是InputCapsule&lt;T&gt;。请注意,这是一种开放类型。目标类型是InputCapsule&lt;string&gt; - 封闭类型。 C# 以非常不同的方式对待它们并将它们视为不同的类型,即使它们都以InputCapsule 开头。见open and closed types

    为了证明它们确实是不同的类型,我可以声明从InputCapsule&lt;T&gt;InputCapsule&lt;string&gt; 的转换:

    public static explicit operator InputCapsule<string>(InputCapsule<T> v)
    {
        return null;
    }
    

    如果它们是同一类型,则根据rules,这是不允许的。

    如果您可以更改User,则应改为在User 中声明转换。

    【讨论】:

      猜你喜欢
      • 2021-06-25
      • 1970-01-01
      • 2022-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多