簡體   English   中英

我可以在方法簽名中強制使用匿名類型嗎?

[英]Can I force anonymous type in method signature?

我已經可以聽到近距離的點擊聲了……大聲笑,哦。

好的,所以我寫了一個采用Dictionary的方法,但后來我有了這個主意,只是傳遞了一個匿名類型,這樣方法調用就不再那么冗長,然后我將其轉換為Dictionary中的Dictionary。

但是,在此更新之后,編譯器不會向我指出任何仍在傳遞字典的調用,因為該參數只是一個對象。

因此,我剛剛開始懷疑是否有一種方法可以將類型強制為匿名? 實際上,我非常確定答案是否定的,如果有人只想發布一個回答為“否”的答案(緊隨其后的字符足以被接受為答案...,也許讓我知道您的請求是多么荒謬的事情。也是如此),那么我會很樂意將其標記為答案。

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

不,您不能使用采用匿名類型的方法-但您可以像cl0ud所說的那樣使用objectdynamic object

但是,我不知道為什么要這樣的事情。 您說要使該方法的調用不再那么冗長-而不是花費更多的字母和按Ctrl + 空格的費用,而是使該方法的用戶遭受潛在的運行時異常,應通過拋出編譯來避免這些異常時間例外。

不用說,這基本上是在放棄c#是一種強類型語言的好處。

如果在執行之前不知道對象的類型,請使用動態

好了,這里使用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

暫無
暫無

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

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