【问题标题】:Method with Generic Type, set value具有通用类型的方法,设置值
【发布时间】:2016-03-08 01:30:58
【问题描述】:

我有一个类似下面的方法,我想用输入字符串设置它的值。

我会怎么做呢?任何建议将不胜感激

private static void QueueCheckNAdd<T>(ref T param, string input)
    {
        param.DoSomethingLikeSetValue(input);
    }

供您参考,泛型类型类似于 int 或 double

【问题讨论】:

  • 如果T 只是intdouble,您可能只想编写几个具体的方法来使用int.Parse()double.Parse() 执行转换。如果您的方法只能用于一小部分固定的类型,那么它就不是真正的通用方法。使用具体方法还允许您编写没有强制转换的方法。
  • 旁注:没有很好的方法将泛型类型限制为int/double - 因此,如果您正在编写可能使用的代码,您需要验证它是否适用于所有允许的类型....
  • 我想考虑到有一天我可能不得不适应不同的类型。我的意思是,现在它只分配给 int 和 double 的数据类型

标签: c# generics methods


【解决方案1】:
param = (T)(object)Convert.ChangeType(input, typeof(T));

强制转换对于让编译器相信结果确实是T 类型是必要的。

【讨论】:

  • 我明白了。非常感谢
【解决方案2】:

您希望param 是通用的(即任何类型),并且您希望能够在其上调用某些方法,对吗?好吧,您可以在那里看到问题:如果param 可以是任何类型,则无法保证它将具有DoSomethingLikeSetValue 方法(或其他方法)。我相信你会喜欢内省或运行时类型强制,但我认为做你正在寻找的“干净”方法是将T的类型限制为具有所需方法的某个接口(@ 987654325@)。像这样:

private static void QueueCheckNAdd<T>(ref T param, string input) where T : IHasSomething {
    param.DoSomethingLikeSetValue(input);
}

public interface IHasSomething {
    void DoSomethingLikeSetValue(string s);
}

只有当泛型类型支持IHasSomething 接口时,你才能泛型调用QueueCheckNAdd。所以你可以这样使用它:

public class Foo : IHasSomething {
    public void DoSomethingLikeSetValue(string s) {
        Console.WriteLine(s);
    }
}

var f = new Foo();
QueueCheckNAdd<Foo>(f, "hello");

【讨论】:

  • 虽然很好的建议你不能真正为内置类型这样做,因为你不能向现有类型添加接口......
  • 这是真的,阿列克谢……这就引出了一个问题:“如果你做不到,你应该做吗?”归根结底,如果类型安全带来如此巨大的不便,您可能应该考虑使用无类型语言。是的,这个问题可以通过 RTTI 或其他方法解决,但它向我表明存在更大的架构问题。
  • 这也是一个很好的方法,我会记住这一点。但我会选择 SLaks 的答案,因为它更干净。虽然性能可能会比较慢
【解决方案3】:

好的做法是使用前面描述的界面,

但如果你想要一些乐趣,你也可以将对象用作动态对象,如下所示:

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

namespace ConsoleApplication1
{
    class SMTHG
    {
        public void DoSomethingLikeSetValue(string input)
        {
            Console.WriteLine("HEYYYYY!!! DYNAMIC OBJECTS FTW!...\n" + input);
        }
    }
    class Program
    {
        private static void QueueCheckNAdd<T>(ref T param, string input)
        {
            dynamic dynamicObject = (dynamic)param; 
            dynamicObject.DoSomethingLikeSetValue(input);
        }
        static void Main(string[] args)
        {
            SMTHG smthg = new SMTHG();
            QueueCheckNAdd(ref smthg, "yoyuyoyo");
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-02
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-15
    • 1970-01-01
    相关资源
    最近更新 更多