问题
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);
}
}
}
回答1:
This has to be done using reflection.
typeof(ExtensionHelpers)
.GetMethod("ToObject", BindingFlags.Static | BindingFlags.Public)
.MakeGenericMethod(returnHeader.Detail.GetType())
.Invoke(null, new object[] { dictDetail });
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 a Type
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.
来源:https://stackoverflow.com/questions/7208101/call-generic-extension-method-with-a-dynamic-type