簡體   English   中英

如何將Generic Type參數傳遞給lambda表達式?

[英]How to pass Generic Type parameter to lambda expression?

我有一個lambda表達式,接受一個int? (可以為空的整數),
如果值存在則返回值,否則返回DBNull.Value

Func<int?, object> getId = id => id.HasValue ? id.Value : (object)DBNull.Value;

這里的目標是,我想使該表達式略微更通用,以便我可以傳遞任何可以為null的類型,如DateTime?

所以這是一個我開始使用的非功能性代碼,但不知道在哪里指定nullable的類型

int? imageId;
DateTime? actionDate;
Func<Nullable<T>, object> getValue = 
    id => id.HasValue ? id.Value : (object) DBNull.Value;
SaveImage(getValue(imageId), getValue(actionDate));

是否可以指定泛型類型或者我應該創建一個命名函數來執行此操作?

由於問題的目的是使用lambda表達式,因此這是一個解決方案。 通過使用弱類型而不是建議的強類型,它采用不同的路線,但仍然完成相同的事情。

        // A lambda solution
        Func<object, object> fnGetValue =
            v =>
                ReferenceEquals(v, null)
                ? DBNull.Value
                : v;


        // Sample usage
        int? one = 1;
        int? two = null;
        object o1 = fnGetValue(one); // gets 1
        object o2 = fnGetValue(two); // gets DBNull

編輯 :這種松散的輸入有效,因為lambda參數v的數據類型是struct本身,而不是Nullable類型的包裝器。 顯然,調用者使用的Nullable值在到達lambda參數時已被解析或“解包”,並且lambda參數顯示結構值或null; Nullable包裝器在這一點上無處可見(或者據我所知)。 可以通過在lambda中將調試斷點放在v並檢查其值來證明此行為。 這種行為的良好副作用是lambda同樣適用於Nullable和非Nullable類型 - 它不受限制。

您可以在Object上創建一個擴展方法來進行轉換,而不是使用泛型。

這是一個示例程序。 ToDbObject擴展進行轉換:

using System;

static class Program
{
    static object ToDbObject(this object value)
    {
        return value ?? DBNull.Value;
    }
    static void Main(string[] args)
    {
        int? imageId = 3; 
        DateTime? actionDate = null;

        Console.WriteLine("ImageId {0}: [{1}] - {2}", imageId, imageId.ToDbObject(), imageId.ToDbObject().GetType());
        Console.WriteLine("actionDate {0}: [{1}] - {2}", actionDate, actionDate.ToDbObject(), actionDate.ToDbObject().GetType());
        Console.ReadKey();
    } 
}

以上打印:

ImageId 3: [3] - System.Int32
actionDate : [] - System.DBNull

它正確處理這兩種情況。

我認為您可以通過創建委托工廠方法來執行此操作,您可以在其中指定泛型類型參數:

public static Func<Nullable<T>, object> CreateGetValueFunc<T>() where T : struct
{
    return id => id.HasValue ? id.Value : (object)DBNull.Value;
}

你可以在你的例子中使用它,如下所示:

SaveImage(
    CreateGetValueFunc<int>()(imageId),
    CreateGetValueFunc<DateTime>()(actionDate));

暫無
暫無

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

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