使用动态类型调用泛型扩展方法
我正在尝试执行一个返回类型 T 的对象的扩展方法,但我正在尝试基于标题/详细信息动态泛型类型使类型 T 动态化。
这可能有点冗长...
using System;
using System.Collections.Generic;
namespace Blah
{
public interface IHeader
{
string Name { get; set; }
IDetail Detail { get; set; }
}
public interface IDetail
{
//Nothing the 'Real' implementation of this
//interface will have it's own properties.
}
public class GenericHeader : IHeader
{
public string Name { get; set; }
public IDetail Detail { get; set; }
}
public class RealHeader : GenericHeader
{
public new RealDetail Detail
{
get { return (RealDetail) base.Detail; }
set { base.Detail = value; }
}
}
public class RealDetail : IDetail
{
public string ThisImportantOnlyToRealDetail { get; set; }
}
public static class ExtensionHelpers
{
public static T ToObject<T>(this IDictionary<string, string> reader) where T : new()
{
//This maps the dictionary to Key Value Pairs of the Object's properties
//it then will return a object filled with the values
return new T();
}
}
public class MyRepo<THeader> where THeader : class, IHeader, new()
{
public THeader GetById(int ID)
{
THeader returnHeader = new THeader();
//Process to fill Header
var dictDetail = new Dictionary<string, string>();
//Process to fill Detail Dictionary
//Use extension method to create an Object
//based on Key Value Pairs from Dictionary
// !!!!!!!!!!!!!!!! This Is The Problem !!!!!!!!!!!!!!!!
// Can't use typeof for returnHeader.Detail, reflection?
returnHeader.Detail = dictDetail.ToObject<typeof(returnHeader.Detail)>();
return returnHeader;
}
}
public class Worker
{
public void DoWork()
{
var myRealRepo = new MyRepo<RealHeader>();
var myRealHeader = myRealRepo.GetById(123);
Console.WriteLine(myRealHeader.Detail.ThisImportantOnlyToRealDetail);
}
}
}
I'm trying to execute an extension method that returns and object of type T, but I'm trying to have type T dynamic based on a Header/Detail dynamic generic type.
This maybe a bit verbose...
using System;
using System.Collections.Generic;
namespace Blah
{
public interface IHeader
{
string Name { get; set; }
IDetail Detail { get; set; }
}
public interface IDetail
{
//Nothing the 'Real' implementation of this
//interface will have it's own properties.
}
public class GenericHeader : IHeader
{
public string Name { get; set; }
public IDetail Detail { get; set; }
}
public class RealHeader : GenericHeader
{
public new RealDetail Detail
{
get { return (RealDetail) base.Detail; }
set { base.Detail = value; }
}
}
public class RealDetail : IDetail
{
public string ThisImportantOnlyToRealDetail { get; set; }
}
public static class ExtensionHelpers
{
public static T ToObject<T>(this IDictionary<string, string> reader) where T : new()
{
//This maps the dictionary to Key Value Pairs of the Object's properties
//it then will return a object filled with the values
return new T();
}
}
public class MyRepo<THeader> where THeader : class, IHeader, new()
{
public THeader GetById(int ID)
{
THeader returnHeader = new THeader();
//Process to fill Header
var dictDetail = new Dictionary<string, string>();
//Process to fill Detail Dictionary
//Use extension method to create an Object
//based on Key Value Pairs from Dictionary
// !!!!!!!!!!!!!!!! This Is The Problem !!!!!!!!!!!!!!!!
// Can't use typeof for returnHeader.Detail, reflection?
returnHeader.Detail = dictDetail.ToObject<typeof(returnHeader.Detail)>();
return returnHeader;
}
}
public class Worker
{
public void DoWork()
{
var myRealRepo = new MyRepo<RealHeader>();
var myRealHeader = myRealRepo.GetById(123);
Console.WriteLine(myRealHeader.Detail.ThisImportantOnlyToRealDetail);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这必须使用反射来完成。
请注意,由于扩展方法是一种语言功能,因此在使用反射时必须像常规静态方法一样调用该方法。
如果类型始终是动态的,则将
ToObject
更改为采用Type
作为参数的常规非泛型方法可能会容易得多。您的设计实际上有点问题,因为您似乎需要知道
Detail
属性背后的对象的实际类型,但这要求该属性已经有一个值,但您的代码正在设置该值财产。我建议您考虑其他方法来处理这个问题。
This has to be done using reflection.
Note that since extension methods are a language feature, you have to call the method like a regular static method when using reflection.
If the type is always dynamic, it's probably a lote easier to change your
ToObject
to be a regular non-generic method that takes aType
as a parameter.Your design is a bit problematic actually, as you seem to need to know the actual type of the object behind the
Detail
property, but that requires that property to already have a value, yet your code is setting that property.I suggest you think about alternative ways to deal with this.