![](/img/trans.png)
[英]Passing in type argument to a method to be used to designate a generic type
[英]Is there a way to derive a type argument from a string for passing into a generic method?
我在記事本++中快速輸入了這個,所以請原諒任何錯別字/錯誤。 如果可能的話,我會擺脫一些重復的工作(即長案例陳述)。 沒什么大不了的,但我很好奇它是否可能,如果可能的話,實際實現代碼會有多糟糕。
jsonFromWebpage = {
StatusUpdate: {
QueryType: "SomeClassName",
LocalCount: 5,
RemoteCount: 5
},
StatusUpdate: {
QueryType: "AnotherClass",
LocalCount: 29,
RemoteCount: 30
}
}
// Model
public class StatusUpdate
{
public string QueryType { get; set; }
public int LocalCount { get; set; }
public int RemoteCount { get; set; }
}
// Controller
public IActionResult GetStatusUpdate([FromBody] List<StatusUpdate> status)
{
_service.GetStatusUpdate(status);
return status
}
// Service
public List<Status> GetStatusUpdate(List<StatusUpdate> status)
{
foreach(var s in status)
{
var typeArgument = s.QueryType; // <--- Is there a way for this...
status.CurrentCount = GetTotalCount<typeArgument>(); // <--- to work here?
status.RemoteCount = thisworksfineforotherreasons(s.QueryType);
}
}
// Repo
public int GetTotalCount<T>() where T: class
{
var result = _db.GetCount<T>();
return result;
}
編輯
首先,感謝所有回復的人。 到目前為止,我已經閱讀了所有內容,我想提供更多背景信息。 這是對示例的不同看法:
// View
<div class="col-12">
<div class="api-types">History</div>
<div class="progress-bar">50 out of 50 copied</div>
</div>
<div class="col-12">
<div class="api-types">Users</div>
<div class="progress-bar">25 out of 32 copied</div>
</div>
// -- View javascript
var types = [];
$(".api-types").each(function (c, i) {
types.push({ ApiAndClassName: $(i).text() });
});
pushToController(JSON.stringify(types));
// Controller
public IActionResult GetSyncStatus(List<SyncStatusVM> status)
{
_service.GetSyncStatus(status);
return Json(status);
}
// Service
public List<SyncStatusVM> GetSyncStatus(List<SyncStatusVM> status)
{
foreach(var s in status)
{
// LocalCount
var magicTypeFigurator = s.ApiAndClassName
s.LocalCount = _repo.GetCount<magicTypeFigurator>(); <-- "this is a variable but should be a type..."
// Remote
var url = $"https://api.domain.com/{s.ApiAndClassName.ToLower()}"
s.RemoteCount = FetchCountFromApi(url);
}
return status;
}
// Repository
public long GetCount<T>()
{
var result = _orm.Count<T>();
return result;
}
// Models
public class SyncStatusVM
{
public string ApiAndClassName { get; set; }
public int LocalCount { get; set; }
public int RemoteCount { get; set; }
}
public class History
{
public long Id {get;set;}
public DateTime CreatedDate {get;set;}
public string Message {get;set;}
}
public class Users
{
public long Id {get;set;}
public string FirstName {get;set;}
public string LastName {get;set;}
}
使用此代碼,我可以在視圖中創建一個部分,並為每種類型創建一個 class。 class 被 ORM 重用,並從 API 反序列化。 最麻煩的一點是在 controller 中有一個 case 語句,它基於“ApiAndClassName”調用具有正確類型的泛型方法。 我可以編輯 ORM 所以它是基於字符串的而不是通用的,但由於各種原因我不喜歡這種方法。 我可以將 case 語句轉換為 controller 中的集合,或者只是將其移動到服務層,但我所擁有的已經有效。 我也可以重構,以便從集合構建視圖,但還有其他數據點不是最佳選擇。 除非我缺少某些東西,否則字符串事物的通用參數是有道理的。 這是一個邊緣案例......有點好奇它是否可以做得足夠好。
一般來說,強類型化是你的朋友。 編譯時類型檢查是一項功能,而不是要戰斗的敵人。 沒有它們或過於激進的鑄造,我們從這部漫畫中得到 JavaScript 和 PHP 示例。
對於弱類型語言或 WebServices,.NET 具有 ExpandoObject。 數據可以存儲在其中,然后傳輸到適當類型的實例中。 此外,您的案例似乎會落入 JSON 反序列化,這是一個完善的代碼。
通用是錯誤的術語。 Generics 通常是關於在編譯時仍然已知的類型,因此編譯時類型檢查仍然有效。 您明確表示在編譯時不知道該類型,僅在運行時才知道。 這與泛型非常不同。 動態類型是正確的術語 afaik。 但是不要將它與 Dynamic 類型混淆(是的,這里的命名變得非常混亂)。
反射是您正在尋找的機器人。 對於大多數用途,運行時不存在 class 或字段的名稱。 它主要是供您和編譯器進行通信的。 現在反射是個例外。 這一切都是關於根據名稱的字符串表示來獲取東西(如實例或屬性/字段)。 必要的元數據被烘焙到 .NET 程序集中,與 COM 支持一樣多。 但由於我支持強類型化,我不是它的朋友。
switch/case 語句通常可以替換為某種集合。 案例實際上只是檢查常量集合的硬編碼方式。 您使用案例標識符作為鍵以及值所需的任何其他內容。 您完全可以使用 Functions 作為值(感謝委托)。 或Type類型,然后用於創建實例。
但是對於您的情況,聽起來所有這些都是錯誤的。 沼澤標准 Inheritance - Inheritance 可能是您正在尋找的真正機器人。 JSON 服務通常不會在單個集合中為您提供不同的實例,除非這些實例以某種方式相關。 “SomeClassName”和“AnotherClass”應該有另一個祖先。 或者實際上,它們甚至應該只是一個 class - QueryType 只是所說 class 的字符串字段。
假設您有辦法將 map 字符串轉換為Type
對象,是的:您可以使用MethodInfo.MakeGenericMethod()
:
var totalCount = (int) (
GetType()
.GetMethod("GetTotalCount")
.MakeGenericMethod(MapStringToType(s.QueryType))
.Invoke(this, null)
);
這假設在本地 scope 中存在方法Type MapStringToType(string)
。
map 類型的一種方法是使用Dictionary<string, Type>
並用允許的類型及其各自的名稱填充它,這些名稱將在 JSON 數據中用於引用它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.