c# - Convert MyClass<SomeType> to MyClass<SomeOtherType> -
using c# 4.0. want convert instance of mybuffer<int>
instance of mybuffer<float>
. converter must general enough handle other basic types too.
i want (or equivalent solution) work. how?
var b1 = mybuffer.create(new int[100]); var b2 = convert.changetype(b1, typeof(mybuffer<float>)); var b3 = convert.changetype(b2, typeof(mybuffer<byte>));
consider mybuffer
class:
public class mybuffer { public static mybuffer<t> create<t>(t[] buffer) t : struct, icomparable, iconvertible { return new mybuffer<t>(buffer); } } public class mybuffer<t> : iconvertible t : struct, icomparable, iconvertible { public t[] buffer { get; set; } public mybuffer() { } public mybuffer(t[] buffer) { buffer = buffer; } public object totype(type conversiontype, iformatprovider provider) { if (conversiontype == gettype()) return this; // first problem: determine if type mybuffer<>. // if (conversiontype == typeof(mybuffer<>)) { if (conversiontype.isgenerictype && conversiontype.getgenericarguments().length > 0) { var buffertype = conversiontype.getgenericarguments()[0]; dynamic newbuffer = buffer. select(s => convert.changetype(s, buffertype)) .toarray(); // second problem: our dynamic variable produce exception here. return mybuffer.create(newbuffer); } } throw new invalidcastexception(); } ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // // completeness... // public typecode gettypecode() { throw new notimplementedexception(); } public bool toboolean(iformatprovider provider) { throw new notimplementedexception(); } public byte tobyte(iformatprovider provider) { throw new notimplementedexception(); } public char tochar(iformatprovider provider) { throw new notimplementedexception(); } public datetime todatetime(iformatprovider provider) { throw new notimplementedexception(); } public decimal todecimal(iformatprovider provider) { throw new notimplementedexception(); } public double todouble(iformatprovider provider) { throw new notimplementedexception(); } public short toint16(iformatprovider provider) { throw new notimplementedexception(); } public int toint32(iformatprovider provider) { throw new notimplementedexception(); } public long toint64(iformatprovider provider) { throw new notimplementedexception(); } public sbyte tosbyte(iformatprovider provider) { throw new notimplementedexception(); } public float tosingle(iformatprovider provider) { throw new notimplementedexception(); } public string tostring(iformatprovider provider) { throw new notimplementedexception(); } public ushort touint16(iformatprovider provider) { throw new notimplementedexception(); } public uint touint32(iformatprovider provider) { throw new notimplementedexception(); } public ulong touint64(iformatprovider provider) { throw new notimplementedexception(); } }
in code above there 2 major problems need solved:
- how determine if
type
variable equalssometype<t>
arbitrary value oft
? - is possible call templated function
t
settype
variable?
since mybuffer<t>
helpfully includes constructor takes buffer wrap argument, can convert 1 buffer manually (very easy linq) , create new "converted" instance:
var b1 = mybuffer.create(new int[100]); var b2 = mybuffer.create(b1.buffer.select(i => (float)i).toarray()); // way same: var b3 = mybuffer.create(b1.buffer.select(convert.tosingle).toarray());
update:
in order assuage daniel's concern might have hidden intentions, here how question asks reflection, of more convenient form runtime digging in place:
dynamic convertarray<t>(t[] input, type target) { var result = array.createinstance(target, input.length); (var = 0; < input.length; ++i) { result.setvalue(convert.changetype(input[i], target), i); } return result; }
this method allows this:
var ints = new[] { 1, 2, 3 }; var strings = convertarray(ints, typeof(string)); foreach (var s in strings) { console.writeline("[{0}] {1}", s.gettype(), s + " potato"); }
as evident, strings
behaves array of strings. of course being dynamic
means particular array never going able mix e.g. lambdas , moral equivalent of reflection still going on @ runtime (only don't see it). it's not quite free lunch, can prove useful @ times.
Comments
Post a Comment