我可以在方法签名中强制使用匿名类型吗?

时间:2018-10-16 06:37:57

标签: c#

我已经可以听到关闭投票的声音了……大声笑,哦。

好吧,所以我写了一个采用Dictionary的方法,但后来我有了这个主意,只是传递了一个匿名类型,这样方法的调用就不再那么冗长,然后我将其转换为方法中的Dictionary。

但是,在此更新之后,编译器不会向我指出任何仍通过字典的调用,因为该参数只是一个对象。

所以我刚开始怀疑是否有一种方法可以将类型强制为匿名?实际上,我非常确定答案是否定的,如果有人只想发布一个回答为“否”的答案(紧随其后的字符足以被接受为答案...,也许让我知道您的请求是多么荒谬的事情。也一样),那么我会很乐意将其标记为答案。

我只是好奇得要问。不要恨我! :)

3 个答案:

答案 0 :(得分:2)

不,您不能使用采用匿名类型的方法-但可以像cl0ud所写的那样使用objectdynamic

但是,我不清楚您为什么要这样的事情。您说要使该方法的调用不再那么冗长-而不是支付输入更多字母并按 ctrl + space 的开销,而是让用户使用这种方法可以避免潜在的运行时异常,应该通过抛出编译时异常来避免这种情况。

不用说,这基本上是在放弃c#是强类型语言这一事实​​的好处。

答案 1 :(得分:1)

如果在执行之前不知道对象的类型,请使用动态

答案 2 :(得分:1)

好吧,这里使用Dictionary有一些利弊(主要是优点)

优点:

  • 不需要其他逻辑
  • 您正在使用C#的优点,因为强类型语言会在编译时引发类型检查异常
  • 高效

缺点:

  • 它需要编写更多代码,并且灵活性较低

如果在传递字典的过程中有大量调用,而性能不是主要问题,则可能要为您的方法创建另一个重载,该方法接受匿名对象,对其进行检查并从中创建字典:

public void MyMethod(object obj)
{
   if (!obj.IsAnonymousType())
   {
      throw new ArgumentException($"Object of this type is not supported!");
   }
   MyMethod(obj.ToDictionary<int>());
}

public void MyMethod(IDictionary<string, int> dict)
{
    // your code here...
}

...

public static class ObjHelper
{
    public static IDictionary<string, T> ToDictionary<T>(this object obj)
    {
        var objType = obj.GetType();

        // This call is optimized by compiler
        var props = objType.GetProperties();

        if (typeof(T) == typeof(object))
        {
            // we don't need to check if property is of certain type
            return props?.ToDictionary(p => p.Name, p => (T)p.GetValue(obj)) ?? new Dictionary<string, T>();
        }
        // It will ignore all types except of T
        return props?.Where(p => p.PropertyType == typeof(T)).ToDictionary(p => p.Name, p => (T)p.GetValue(obj)) ?? new Dictionary<string, T>();
    }

    public static bool IsAnonymousType(this object obj)
    {
        var type = obj.GetType();

        if (type == null)
        {
            throw new ArgumentNullException("type");
        }

        return Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false)
               && type.IsGenericType && type.Name.Contains("AnonymousType")
               && (type.Name.StartsWith("<>") || type.Name.StartsWith("VB$"))
               && (type.Attributes & TypeAttributes.NotPublic) == TypeAttributes.NotPublic;
    }
}

并命名为:

MyMethod(new 
{
   foo = 15,
   bar = 8
})

让我们与普通的dict通话进行比较:

MyMethod(new Dictionary<string, int>() 
{
   { "foo", 15 },
   { "bar", 8 },
})

100000次操作的平均性能(以毫秒为单位):

  • 通过匿名课程致电:270
  • 用字典呼叫:10