簡體   English   中英

使用“Convert.ChangeType()”將System.String一般轉換為任何復雜類型

[英]Convert System.String generically to any complex type using “Convert.ChangeType()”

我嘗試將用戶輸入一般轉換為簡單或復雜類型:

class Program
{
  static void Main(string[] args)
  {
    Console.WriteLine("Welcome, please provide the following info... Confirm with <RETURN>!");
    Console.WriteLine();    

    Console.Write("Name (e.g. 'Peggy Sue'): ");
    var user = GetUserInput<User>(Console.ReadLine());

    Console.WriteLine();
    Console.WriteLine();
    Console.WriteLine("Hi {0}, nice to meet you!", user.Forename);
    Console.WriteLine();

    Console.Write("Age: ");
    user.Age = GetUserInput<ushort>(Console.ReadLine());

    Console.WriteLine();
    Console.WriteLine("Thanks and goodbye!");
    Console.WriteLine("Press <RETURN> to quit...");
    Console.ReadLine();
  }

  static T GetUserInput<T>(string data)
  {
    return (T) Convert.ChangeType(data, typeof (T));
  }
}

class User
{
  public User(string name)
  {
    var splitted = name.Split(' ');
    Forename = splitted[0];
    Lastname = splitted[1];
  }

  public static implicit operator User (string value)
  {
    return new User(value);
  }

  public static explicit operator string (User value)
  {
    return string.Concat(value.Forename, " ", value.Lastname);
  }

  public string Forename { get; private set; }
  public string Lastname { get; private set; }

  public ushort Age { get; set; }
}

為了轉換到我的“User”類,我總是得到異常“從'System.String'到'ConsoleApplication1.User'的無效轉換。”。 有誰知道如何解決這一問題?

如果我嘗試這樣的東西(不是一般),它的工作就完美了:

Console.WriteLine((string) ((User) "Peggy Sue"));

不, Convert.ChangeType只適用於一組固定的類型,我相信......或者如果原始對象實現了IConvertible ,它可以調用IConvertible.ToType 這意味着您可以User類中實現IConvertible並具有

Convert.ChangeType(user, typeof(string))

工作,但這不會相反。

您是否有需要轉換的固定類型? 如果是這樣,您可以使用轉換委托填充的Dictionary<Type, Func<string, object>> 然后你只需要調用適當的轉換並轉換返回值。 這很難看,但可能是你最好的選擇。

這里的一個選項可能是將TypeConverter與您關注的類型相關聯(您可以在編譯時通過[TypeConverter(...)]執行此操作,或者如果您不控制,則可以在運行時執行此操作類型)。

然后它是:

TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
T obj = (T)conv.ConvertFromString(text); // or ConvertFromInvariantString

我修好了它。 檢查一下:

class Program
{
  static void Main(string[] args)
  {
    Console.WriteLine("Welcome, please provide the following info... Confirm with <RETURN>!");
    Console.WriteLine();

    Console.Write("Name (e.g. 'Peggy Sue'): ");
    var user = GetUserInput<User>(Console.ReadLine());

    Console.WriteLine();
    Console.WriteLine();
    Console.WriteLine("Hi {0}, nice to meet you!", user.Forename);
    Console.WriteLine();

    Console.Write("Age: ");
    user.Age = GetUserInput<ushort>(Console.ReadLine());

    Console.WriteLine();
    Console.WriteLine("Thanks and goodbye!");
    Console.WriteLine("Press <RETURN> to quit...");
    Console.ReadLine();
  }

  static T GetUserInput<T>(string data)
  {
    TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
    return (T) conv.ConvertFromInvariantString(data);
  }
}

[TypeConverter(typeof(UserConverter))]
class User
{
  public User(string name)
  {
    var splitted = name.Split(' ');
    Forename = splitted[0];
    Lastname = splitted[1];
  }

  public static explicit operator User (string value)
  {
    return new User(value);
  }

  public static explicit operator string (User value)
  {
    return string.Concat(value.Forename, " ", value.Lastname);
  }

  public string Forename { get; private set; }
  public string Lastname { get; private set; }

  public ushort Age { get; set; }
}

class UserConverter : TypeConverter
{
  public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
  {
    return (typeof(string) == sourceType);
  }

  public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
  {
    if (value is string)
    {
      return (User)(value as string);
    }

    return null;
  }
}

如果你想轉換為數字類型,我更喜歡更簡潔和意圖暴露:

decimal.Parse(someString)

或者,在您的示例中:

new User(userName)

沒有理由創建一個完整的方法(或類,如果你決定將來“使這個可重用”)只是為了包裝一個演員。 當語言已經采用不太透明的方式來表達代碼的意圖時,尤其如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM