C# 转换MyClass<;SomeType>;给我的班级<;其他类型>;
使用C#4.0。我想将C# 转换MyClass<;SomeType>;给我的班级<;其他类型>;,c#,generics,C#,Generics,使用C#4.0。我想将MyBuffer的实例转换为MyBuffer的实例。转换器必须足够通用,以处理其他基本类型 我希望这个(或等效的解决方案)能起作用。怎么做? var b1 = MyBuffer.Create(new int[100]); var b2 = Convert.ChangeType(b1, typeof(MyBuffer<float>)); var b3 = Convert.ChangeType(b2, typeof(MyBuffer<byte>));
MyBuffer
的实例转换为MyBuffer
的实例。转换器必须足够通用,以处理其他基本类型
我希望这个(或等效的解决方案)能起作用。怎么做?
var b1 = MyBuffer.Create(new int[100]);
var b2 = Convert.ChangeType(b1, typeof(MyBuffer<float>));
var b3 = Convert.ChangeType(b2, typeof(MyBuffer<byte>));
在我上面的代码中,有两个主要问题需要解决:
T
,如何确定Type
变量是否等于SomeType
T
设置为某个Type
变量的模板函数MyBuffer
包含了一个将缓冲区包装为参数的构造函数,因此非常有用,您只需手动将一个缓冲区转换为另一个缓冲区(使用LINQ非常容易),并创建一个新的“转换”实例:
var b1 = MyBuffer.Create(new int[100]);
var b2 = MyBuffer.Create(b1.Buffer.Select(i => (float)i).ToArray());
// another way to do the same:
var b3 = MyBuffer.Create(b1.Buffer.Select(Convert.ToSingle).ToArray());
更新:
为了缓解人们对我可能有隐藏意图的担忧,下面是如何通过反思来完成问题所要求的,但更方便的形式是运行时在您的位置进行挖掘:
dynamic ConvertArray<T>(T[] input, Type target) {
var result = Array.CreateInstance(target, input.Length);
for (var i = 0; i < input.Length; ++i)
{
result.SetValue(Convert.ChangeType(input[i], target), i);
}
return result;
}
很明显,字符串
的行为与字符串数组完全相同。当然,动态
意味着这个特定的数组永远无法与lambdas混合,并且在运行时仍在进行道德上的反射(只有你看不到)。因此,它不是一顿免费的午餐,但有时会被证明是有用的。由于MyBuffer
非常有用地包含了一个将缓冲区包装为参数的构造函数,您只需手动将一个缓冲区转换为另一个缓冲区(使用LINQ非常容易),并创建一个新的“转换”实例:
var b1 = MyBuffer.Create(new int[100]);
var b2 = MyBuffer.Create(b1.Buffer.Select(i => (float)i).ToArray());
// another way to do the same:
var b3 = MyBuffer.Create(b1.Buffer.Select(Convert.ToSingle).ToArray());
更新:
为了缓解人们对我可能有隐藏意图的担忧,下面是如何通过反思来完成问题所要求的,但更方便的形式是运行时在您的位置进行挖掘:
dynamic ConvertArray<T>(T[] input, Type target) {
var result = Array.CreateInstance(target, input.Length);
for (var i = 0; i < input.Length; ++i)
{
result.SetValue(Convert.ChangeType(input[i], target), i);
}
return result;
}
很明显,字符串
的行为与字符串数组完全相同。当然,动态
意味着这个特定的数组永远无法与lambdas混合,并且在运行时仍在进行道德上的反射(只有你看不到)。因此,这不是一顿免费的午餐,但有时会证明它很有用。关于第一个问题:
if (conversionType.GetGenericTypeDefinition() == typeof(MyBuffer<>))
if(conversionType.GetGenericTypeDefinition()==typeof(MyBuffer))
关于第二个问题:
//your method....
//....
if (conversionType.IsGenericType && conversionType.GetGenericArguments().Length > 0)
{ //in fact you don't need this if in case the first problem is solved.
var bufferType = conversionType.GetGenericArguments()[0];
Func<MyBuffer<object>> AuxMethod = BufferConversion<object>;
return AuxMethod.Method.GetGenericMethodDefinition().MakeGenericMethod(bufferType).Invoke(this, null);
}
//....continue your method....
private MyBuffer<NewType> BufferConversion<NewType>()
{
NewType[] MyNewArray = Buffer.Select(s => (NewType)Convert.ChangeType(s, typeof(NewType))).ToArray();
return MyBuffer.Create(MyNewArray);
}
//您的方法。。。。
//....
if(conversionType.IsGenericType&&conversionType.GetGenericArguments().Length>0)
{//事实上,如果第一个问题解决了,你不需要这个。
var bufferType=conversionType.GetGenericArguments()[0];
Func AuxMethod=缓冲转换;
返回AuxMethod.Method.GetGenericMethodDefinition().MakeGenericMethod(bufferType).Invoke(此为null);
}
//……继续你的方法。。。。
私有MyBuffer BufferConversion()
{
NewType[]MyNewArray=Buffer.Select(s=>(NewType)Convert.ChangeType(s,typeof(NewType))).ToArray();
返回MyBuffer.Create(MyNewArray);
}
到第一个问题:
if (conversionType.GetGenericTypeDefinition() == typeof(MyBuffer<>))
if(conversionType.GetGenericTypeDefinition()==typeof(MyBuffer))
关于第二个问题:
//your method....
//....
if (conversionType.IsGenericType && conversionType.GetGenericArguments().Length > 0)
{ //in fact you don't need this if in case the first problem is solved.
var bufferType = conversionType.GetGenericArguments()[0];
Func<MyBuffer<object>> AuxMethod = BufferConversion<object>;
return AuxMethod.Method.GetGenericMethodDefinition().MakeGenericMethod(bufferType).Invoke(this, null);
}
//....continue your method....
private MyBuffer<NewType> BufferConversion<NewType>()
{
NewType[] MyNewArray = Buffer.Select(s => (NewType)Convert.ChangeType(s, typeof(NewType))).ToArray();
return MyBuffer.Create(MyNewArray);
}
//您的方法。。。。
//....
if(conversionType.IsGenericType&&conversionType.GetGenericArguments().Length>0)
{//事实上,如果第一个问题解决了,你不需要这个。
var bufferType=conversionType.GetGenericArguments()[0];
Func AuxMethod=缓冲转换;
返回AuxMethod.Method.GetGenericMethodDefinition().MakeGenericMethod(bufferType).Invoke(此为null);
}
//……继续你的方法。。。。
私有MyBuffer BufferConversion()
{
NewType[]MyNewArray=Buffer.Select(s=>(NewType)Convert.ChangeType(s,typeof(NewType))).ToArray();
返回MyBuffer.Create(MyNewArray);
}
把这个扔出去。有一个很棒的库,用于转换对象类型,称为AutoMapper
把这个扔出去。有一个很棒的库,用于转换对象类型,称为AutoMapper
是的,但我想解决一个更普遍的问题。给定一个
SomeClass
实例,如何将其转换为同一类,但使用不同类型的T
?@l33t由于可能的转换有限,您希望如何解决这两种类型的问题?任何基本类型<代码>字节,int
,short
,float
,double
及其有符号/无符号对应项。也可能是bool
@l33t:假设您有一个方法Foo
,该方法将类型
作为参数(要转换的缓冲区类型)并神奇地执行您想要的操作(返回转换后的缓冲区)。方法的返回类型是什么?您自己的尝试返回对象
——您将如何处理此对象
?我想说的是:一旦你越过这条线进入反射之地,你就再也回不来了。也许用不同的设计能更好地满足您的需求。这个答案很好,除非您有未提及的隐藏意图。是的,但我正在尝试解决一个更普遍的问题。给定一个SomeClass
实例,如何将其转换为同一类,但使用不同类型的T
?@l33t由于可能的转换有限,您希望如何解决这两种类型的问题?任何基本类型<代码>字节,int
,short
,float
,double
及其有符号/无符号对应项。也可能是bool
@l33t:假设您有一个方法Foo
,该方法将类型
作为参数(要转换的缓冲区类型)并神奇地执行您想要的操作(返回转换后的缓冲区)。方法的返回类型是什么?您自己的尝试返回对象
——您将如何使用