簡體   English   中英

使用反射調用泛型方法的輔助方法

[英]Helper method for calling generic methods with reflection

有沒有人有更好的方法來執行以下操作:

typeof(Service).GetMethod("UpdateData")
    .MakeGenericMethod(dataType)
    .Invoke(_myService, new object[]{ editData, metaData });

我想做類似的事情:

_myService.UpdateData<dataType>(editData, metaData);

但是泛型的 <> 訪問器不會接受 Type 對象。 我正在尋找一個幫助器、實用程序、訪問器或其他東西來使那些帶有反射的通用方法調用不那么麻煩或至少是集中的。

更具體的例子

public class UserService : IUserService
{
  async Task<User> UpdateUser<T>(User user, JsonPatchDocument<T> patch){ //do code }
}

Type dtoType = MagicService.getDynamicDtoType();
Type patchType = typeof(JsonPatchDocument<>).MakeGenericType(dtoType);
dynamic patchDoc = _mapper.Map(patch, typeof(JsonPatchDocument<User>), patchType);
User updateUser = await (Task<User>)typeof(UserService).GetMethod("UpdateUser").MakeGenericMethod(dtoType).Invoke(_userService, new object[]{user, patchDoc})

這實際上會導致兩個問題。 一, dynamic patchDoc不是在UpdateUser使用的正確類型,我在 Stackoverflow 中有一個單獨的問題(但您可以在此處使用鴨子類型),以及使用反射調用該通用方法調用的混亂調用。 我正在嘗試解決這兩個問題,但對於這個問題,我想清理電話。 如果您對另一部分有想法,這實際上是一個單獨的問題: 在 C# 中使用 Type 實例聲明類型

此答案不使用反射,但在某些情況下可能會使您的代碼更易於使用。

我們可以有一個這樣的類:

public class MyService
{
    public void UpdateData<T>(Something data, Something otherData)
    {
        // do stuff
    }
}

后來我們發現我們必須使用Type變量而不是泛型參數來調用它,這可能意味着使用反射。 有時向原始類添加非泛型重載並從泛型方法中調用它會更容易:

public class MyService
{
    public void UpdateData(Type dataType, Something data, Something otherData)
    {
        // do stuff
    }

    public void UpdateData<T>(Something data, Something otherData)
    {
        UpdateData(typeof(T), data, otherData);
    }
}

我們失去了像使用泛型方法那樣輕松地對Type參數施加約束的能力。 如果需要,我們可以添加驗證。

這使您盡可能接近您嘗試編寫的代碼:

_myService.UpdateData(dataType, editData, metaData);

那是假設您發現自己仍然需要通用方法。 如果添加非泛型重載並發現不再調用泛型重載,則可以刪除它們。

這種過度反射的一個顯着好處是您可以確定調用代碼的位置。 僅使用反射調用的方法將顯示為未使用。

暫無
暫無

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

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