[英]How can I find out wether the current object is object<T> or object<T,U> in C#
我想知道 C# 中是否有辦法找出對象是object<>
還是object<T,U>
。
在我的程序中,我處理ConsoleCommand
。
這些類繼承自ConsoleCommandBase
類。
ConsoleCommand
類是ConsoleCommand
、 ConsoleCommand<>
或ConsoleCommand<T,U>
。
我的目標是在運行時確定我當前正在查看哪個特定的ConsoleCommand
。 我不想寫很多 if-else 語句來確定當前對象類型,就像我在代碼中所做的那樣。 因此,我可以添加第三個ConsoleCommand<T,U,V>
而無需觸及此代碼。
這是我當前的代碼。 它有效,但我必須知道它是typeof(ConsoleCommand<>)
還是typeof(ConsoleCommand<T,U>)
。
for (int i = 0; i < commandList.Count; i++)
{
if (properties[0].Equals(commandList[i].Id))
{
if (commandList[i] is ConsoleCommand)
{
(commandList[i] as ConsoleCommand).Invoke();
validCommand = true;
break;
}
else
{
validCommand = false;
var command = commandList[i];
Type[] types = command.GetMyTypes();
if(properties.Length - 1 >= types.Length)
{
var typeOfCommand = typeof(ConsoleCommand<,>);
var genericType = typeOfCommand.MakeGenericType(types);
object[] parameters = new object[types.Length];
for(int j=0; j<types.Length; j++)
{
parameters[j] = ConvertType(properties[j + 1], types[j]);
}
genericType.GetMethod("Invoke").Invoke(command, parameters);
validCommand = true;
}
break;
}
}
}
實際上,您已經擁有所需的代碼,只需將其泛化即可。
例如(我對您的代碼進行了一些重構,以改進並使其適用於示例)
class Foo<X,Z> {
public string Invoke(X x, Z z) => $"{x} {z}";
}
class Bar<A,B,C> {
public string Invoke(A a, B b, C c) => $"{a} {b} {c}";
}
//then to test
var foo = new Foo<string, int>();
callCommand(foo, new string[] { "id", "a", "1" });
var bar = new Bar<string, int, double>();
callCommand(bar, new string[] { "id", "a", "2", "3.1"});
void callCommand(object command, string[] properties){
var typeOfCommand = command.GetType();
var types = typeOfCommand.GetGenericArguments();
//var genericType = typeOfCommand.MakeGenericType(types);
object[] parameters = new object[types.Length];
for(int j=0; j<types.Length; j++)
{
parameters[j] = Convert.ChangeType(properties[j + 1], types[j]);
}
var x = typeOfCommand.GetMethod("Invoke").Invoke(command, parameters);
Console.WriteLine(x);
}
話雖如此,解析命令行有更好的替代方法,尤其是在 .net core 中。 例如System.CommandLine和DragonFruit
你可以做這樣的事情。
以下是一些輔助方法。
static bool IsInstanceOf(Type typeToCheck, object instance)
{
if(typeToCheck.IsGenericType)
{
return IsInstanceOfGenericType(typeToCheck, instance);
}
else
{
return instance.GetType() == typeToCheck;
}
}
static bool IsInstanceOfGenericType(Type genericType, object instance)
{
Type type = instance.GetType();
while (type != null)
{
if (type.IsGenericType &&
type.GetGenericTypeDefinition() == genericType)
{
return true;
}
type = type.BaseType;
}
return false;
}
用法。
ConsoleCommandBase v1 = new ConsoleCommand();
ConsoleCommandBase v2 = new ConsoleCommand<int>();
ConsoleCommandBase v3 = new ConsoleCommand<int, int>();
Console.WriteLine(IsInstanceOf(typeof(ConsoleCommand), v1));
Console.WriteLine(IsInstanceOf(typeof(ConsoleCommand), v2));
Console.WriteLine(IsInstanceOf(typeof(ConsoleCommand),v3));
Console.WriteLine(IsInstanceOf(typeof(ConsoleCommand<>), v1));
Console.WriteLine(IsInstanceOf(typeof(ConsoleCommand<>), v2));
Console.WriteLine(IsInstanceOf(typeof(ConsoleCommand<>), v3));
Console.WriteLine(IsInstanceOf(typeof(ConsoleCommand<,>), v1));
Console.WriteLine(IsInstanceOf(typeof(ConsoleCommand<,>), v2));
Console.WriteLine(IsInstanceOf(typeof(ConsoleCommand<,>), v3));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.