using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
namespace Gen.ConsoleApp24
{
class Program
{
static async Task Main(string[] args)
{
var aliRequestMessage = new AliRequestMessage { ProductInfo = new AliProductInfo { MyVar = new AliVar(), Sale = new AliSale() } };
//使用泛型做爲傳參類型
var fun = new Func<RequestMessage<ProductInfo>, Task<string>>(async message =>
{
//var productInfo = (ProductInfo<Var, Sale>)message.ProductInfo;//運行時轉換會報錯,如果取值請通過反射或委託回調轉成具體的類型去處理
Console.WriteLine(message.Name);
Console.WriteLine(message.GetType().Name);
Console.WriteLine(message.ProductInfo.GetType().Name);
return await Task.FromResult(message.Name);
});
//await fun(aliRequestMessage);//編譯報錯
//解決方法1: 定義一個空子類ChildRequestMessage 繼承泛型
await fun(new JdRequestMessage() { ProductInfo = new JdProductInfo { MyVar = new JdVar(), Sale = new JdSale() } });
//解決方法2(推薦): 將泛型繼承一個基類,用基類做爲傳參類型
var fun2 = new Func<RequestMessage, Task<string>>(async message =>
{
//var productInfo = (ProductInfo<Var, Sale>)message.ProductInfo;//編譯報錯,如果取值請通過反射或委託回調轉成具體的類型去處理
Console.WriteLine(message.Name);
Console.WriteLine(message.GetType().Name);
//Console.WriteLine(message.ProductInfo.GetType().Name);//編譯報錯
return await Task.FromResult(nameof(message));
});
await fun2(aliRequestMessage);
//解決方法3: 使用表達式做爲傳參類型
var funExpr = new Func<Expression<Func<RequestMessage<ProductInfo>, object>>, Task<string>>(async expression =>
{
RequestMessage message = null;
if (expression.NodeType == ExpressionType.Constant)
{
message = (RequestMessage)((ConstantExpression)expression.Body).Value;
}
else
{
var memberExpression = (MemberExpression)expression.Body;
var @object = ((ConstantExpression)(memberExpression.Expression)).Value;
if (memberExpression.Member.MemberType == MemberTypes.Field)
{
message = (RequestMessage)((FieldInfo)memberExpression.Member).GetValue(@object);
}
else if (memberExpression.Member.MemberType == MemberTypes.Property)
{
message = (RequestMessage)((PropertyInfo)memberExpression.Member).GetValue(@object);
}
}
//var productInfo = (ProductInfo<Var, Sale>)message.ProductInfo;//編譯報錯
Console.WriteLine(message.Name);
Console.WriteLine(message.GetType().Name);
//Console.WriteLine(message.ProductInfo.GetType().Name);//編譯報錯
return await Task.FromResult(nameof(message));
});
await funExpr(p => aliRequestMessage);
Console.WriteLine("Hello World!");
}
}
public class AliRequestMessage : RequestMessage<AliProductInfo>
{
public string AliName { get; set; } = "Ali";
}
public class AliProductInfo : ProductInfo<AliVar, AliSale>
{
}
public class AliVar : Var
{
}
public class AliSale : Sale
{
}
public class JdRequestMessage : ChildRequestMessage
{
public string JdName { get; set; } = "JD";
}
public class JdProductInfo : ProductInfo<JdVar, JdSale>
{
}
public class JdVar : Var
{
}
public class JdSale : Sale
{
}
public class RequestMessage
{
public string Name { get; set; } = "xxx";
}
public class ChildRequestMessage : RequestMessage<ProductInfo>
{
}
public class RequestMessage<TProductInfo> : RequestMessage where TProductInfo : ProductInfo
{
public TProductInfo ProductInfo { get; set; }
}
public class ProductInfo
{
}
public class ProductInfo<TVar, TSale> : ProductInfo where TVar : Var where TSale : Sale
{
public TVar MyVar { get; set; }
public TSale Sale { get; set; }
}
public class Var
{
public string Name { get; set; } = "變體";
}
public class Sale
{
public string Name { get; set; } = "賣家";
}
}
運行效果: