【问题标题】:Is there a way to invoke a templated class on an anonymous type?有没有办法在匿名类型上调用模板类?
【发布时间】:2016-08-07 08:16:48
【问题描述】:

这里有一些代码来给出这个想法。

public class C<T> { }
public class X {
  void M() {
    var V = new { W = 1 };
    var X = new C<V>(); // illegal
  }
}

所以 V 是一个匿名类型的变量,我想用 V 作为参数来实例化 C 类。这需要一个我无法提供的类型参数。

这个问题很相似,但对我来说答案没有多大帮助:Why can't I instantiate a generic class inferring types from anonymous objects?

问题背后的问题是我正在尝试做 IEnumerable 可以做的事情。


应该说清楚:我真的不希望通过操纵 objectType 来做到这一点,因为你失去了强类型和 Intellisense 的好处。


对于任何感兴趣的人,此处描述了需要此功能的项目:http://www.andl.org/2016/07/andl-net-making-progress/

【问题讨论】:

  • 可以分享一下C的完整代码
  • 您链接到的问题的答案是关于通过辅助方法使用类型推断:C&lt;T&gt; MakeC&lt;T&gt;(T arg) { return new C&lt;T&gt;(); } - 它启用了以下功能:var X = MakeC(V);。这怎么不能回答你的问题?
  • @DevEstacion:不是真的,还不存在!这是实验性的,试图产生类似IEnumerable&lt;T&gt; 的东西,但不是。
  • @PieterWitvoet:接受的答案使用了一个帮助器 class(并且有很多喋喋不休)。我猜我错过了关键位是辅助方法

标签: c# generics anonymous-types


【解决方案1】:

如果你有工厂方法,你可以使用类型推断:

public class C<T>
{
    public C(T t)
    {
        // ...
    }
}

public static class Factory
{
    public static C<T> Create<T>(T t)
    {
        return new C<T>(t);
    }
}

public class Thing
{
    void Foo()
    {
        var x = new { y = "z" };
        //var thing = new C(x); - doesn't work, you need to specify the generic parameter
        var thing = Factory.Create(x); // T is inferred here
    }
}

【讨论】:

  • 如此简单。是的,我可以多次使用该模式来解决一系列相关问题。为什么我没有想到呢?见编辑。
【解决方案2】:

您不能这样做,因为 V 是匿名类型的实例,而不是类型名称本身。

您可以动态创建此类型(假设 C 中的无参数构造函数):

var X = typeof (C<>)
            .MakeGenericType(V.GetType())
            .GetConstructor(Type.EmptyTypes)
            .Invoke(new object[0]);

【讨论】:

  • 非常好,为此 +1。绝对是我会使用的东西,但这次不会。请参阅编辑了解原因。
【解决方案3】:

你需要一个type,你可以使用传递object作为一个type。

示例代码:

public class C<T> 
{
    public T _t { get; set; }

    public C(T t)
    {
        _t = t;
    }

    public void TestMethod()
    {
        Console.WriteLine(_t.ToString());
    }
}

public class X
{
    public void M()
    {

        var V = new { W = 1 };

        var X = new C<object>(V); // everything is an object.

        X.TestMethod();
    }
}

【讨论】:

  • 谢谢,但我真的很想保持强类型。见编辑。
  • @david.pfx:我明白你的意思了,恭喜你找到了正确的解决方案
猜你喜欢
  • 2011-02-13
  • 2010-11-22
  • 2013-04-21
  • 2018-07-21
  • 1970-01-01
  • 1970-01-01
  • 2022-11-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多