【问题标题】:Setting a TSource value to a String将 TSource 值设置为字符串
【发布时间】:2025-11-28 02:55:02
【问题描述】:

我需要操作一个TSource 变量。

//代码:

 private static DataTable ToDataTable<TSource>(this IList<TSource> data)
  {
          foreach (TSource item in data)
            {
                switch (item.ToString())
                 {
                    case "Name":
                        item = "John";  //Error here
                        break;
                 }
            }
  }

错误:

Cannot implicitly convert type string to TSource.

有什么建议吗?

【问题讨论】:

  • 这段代码将如何编译?您不能分配给项目,因为它在 foreach 内
  • 为什么要将项目设置为字符串?如果您想将 item 用作字符串,为什么要使用 Generic 类?

标签: c# .net type-conversion


【解决方案1】:

由于 TSource 是泛型类型,您无法确保到 string 的转换是有效的,所以 item = "John"; 总是向您显示编译错误。

我认为您有几种可能性:

  • 可以假设集合不是TSource类型,设置为IList&lt;string&gt;
  • 您可以定义一个可以从字符串显式分配的基本类型。

例如:

internal class StringConvertible
{
    public static implicit operator string(StringConvertible value)
    {
        return value.StringValue;
    }

    public static implicit operator StringConvertible(string value)
    {
        return new StringConvertible
        {
            StringValue = value
        };
    }

    public virtual string StringValue { get; set; }
}

// ...

private static DataTable ToDataTable<TSource>(this IList<TSource> data)
{
    for (int index = 0; index < data.Count; index++)
    {
        if (!typeof(TSource).IsAssignableFrom(typeof(StringConvertible)))
        {
            continue;
        }

        StringConvertible value = data[index] as StringConvertible;
        switch (value)
        {
            case "Name":
                value.StringValue = "John";
                break;
        }     
    }

    // ...
}

【讨论】:

  • 至少有两个错误:StringConvertible value = (StringConvertible)(object)item; 您需要对对象进行中间转换,或者您必须使用StringConvertible value = item as StringConvertible。第二个,更重要的是你不能return new StringConvertible(value),因为StringConvertible是一个抽象类,然后你真的要创建一个TSource
  • 操作!是的...示例已删除!
  • 使用虚拟抽象 getter/setter 的更好示例(公共抽象字符串 StringValue { get; set; })。并且修改正在枚举的项目是必须“谨慎”完成的事情
【解决方案2】:

除了 HuorSwords 指出的那些选项之外,另一个选项可能是将自定义转换函数传递给 ToDataTable,如下所示:

private static DataTable ToDataTable<TSource>(this IList<TSource> data, Func<string, TSource> itemFromString)
  {
          foreach (TSource item in data)
            {
                switch (item.ToString())
                 {
                    case "Name":
                        item = itemFromString("John");
                        break;
                 }
            }
  }

【讨论】: