c#-从参数类型未知的函数调用良好的重载方法
我试图从参数类型未知的函数调用良好的重载方法。但我总是有一个转换错误。 我怎么能这样做 Ps我尝试不使用if来检查类型 我试图将我的函数更改为泛型,但我遇到了一个转换错误c#-从参数类型未知的函数调用良好的重载方法,c#,generics,dynamic,struct,reference,C#,Generics,Dynamic,Struct,Reference,我试图从参数类型未知的函数调用良好的重载方法。但我总是有一个转换错误。 我怎么能这样做 Ps我尝试不使用if来检查类型 我试图将我的函数更改为泛型,但我遇到了一个转换错误 "Impossible to convert ref T in ref MYPROGRAM.MYCLASS.Struct1" 我的节目: public struct Struct1 {...} public struct Struct2 {...} public void EditStruct(ref Struct1 S
"Impossible to convert ref T in ref MYPROGRAM.MYCLASS.Struct1"
我的节目:
public struct Struct1
{...}
public struct Struct2
{...}
public void EditStruct(ref Struct1 StrucToEdit)
{...}
public void EditStruct(ref Struct2 StrucToEdit)
{...}
public void MyFunction<T>(ref T UnknownStruct)
{
EditStruct(ref UnknownStruct)
}
public结构1
{...}
公共结构2
{...}
public void EditStruct(参考Struct1 StrucToEdit)
{...}
public void EditStruct(参考Struct2 StrucToEdit)
{...}
public void MyFunction(ref T UnknownStruct)
{
EditStruct(参考未知结构)
}
Thx很多。我甚至不知道你在做什么,但是不需要对通用方法进行任何转换,类型已经知道了 只需调用EditStruct(ref unknownstuctcasted),删除第一行 参数的类型为T,而不是
动态。只有当你调用你的方法
EditStruct(new dynamic{
//some data
});
你不是吗
工作样本:
internal class Program
{
public enum WhatToDo
{
Something,
SomethingElse
}
public static void MyMethod(WhatToDo what)
{
switch (what)
{
case WhatToDo.Something:
Struct1 param1 = new Struct1();
MygenericMethod(param1);
break;
case WhatToDo.SomethingElse:
Struct2 param2 = new Struct2();
MygenericMethod(param2);
break;
}
}
public static void MygenericMethod<T>(T someParam) where T : struct
{
}
public struct Struct1
{
}
public struct Struct2
{
}
}
内部类程序
{
公共枚举什么
{
某物
某物
}
公共静态无效MyMethod(WhatDoWhat)
{
开关(什么)
{
凯斯:我该怎么办
Struct1 param1=新Struct1();
MygenericMethod(参数1);
打破
case Whatdo.有些事情:
Struct2 param2=新的Struct2();
MygenericMethod(参数2);
打破
}
}
公共静态void MygenericMethod(T someParam),其中T:struct
{
}
公共结构1
{
}
公共结构2
{
}
}
我甚至不明白你在做什么,但是不需要对泛型方法进行任何转换,类型已经知道了
只需调用EditStruct(ref unknownstuctcasted)
,删除第一行
参数的类型为T,而不是动态。只有当你调用你的方法
EditStruct(new dynamic{
//some data
});
你不是吗
工作样本:
internal class Program
{
public enum WhatToDo
{
Something,
SomethingElse
}
public static void MyMethod(WhatToDo what)
{
switch (what)
{
case WhatToDo.Something:
Struct1 param1 = new Struct1();
MygenericMethod(param1);
break;
case WhatToDo.SomethingElse:
Struct2 param2 = new Struct2();
MygenericMethod(param2);
break;
}
}
public static void MygenericMethod<T>(T someParam) where T : struct
{
}
public struct Struct1
{
}
public struct Struct2
{
}
}
内部类程序
{
公共枚举什么
{
某物
某物
}
公共静态无效MyMethod(WhatDoWhat)
{
开关(什么)
{
凯斯:我该怎么办
Struct1 param1=新Struct1();
MygenericMethod(参数1);
打破
case Whatdo.有些事情:
Struct2 param2=新的Struct2();
MygenericMethod(参数2);
打破
}
}
公共静态void MygenericMethod(T someParam),其中T:struct
{
}
公共结构1
{
}
公共结构2
{
}
}
非常小的OO示例可能会有所帮助-在本例中,使用IStructEditor
界面封装执行编辑的代码:
public static class StructEditor
{
public static void Edit<TStruct, TEditor>(ref TStruct s)
where TEditor : IStructEditor<TStruct>, new()
{
new TEditor()
.EditStuct(ref s);
}
}
public interface IStructEditor<T>
{
void EditStuct(ref T s);
}
struct CostStruct
{
public int Cost;
}
class SetCost
: IStructEditor<CostStruct>
{
public void EditStuct(ref CostStruct s)
{
s.Cost = 123;
}
}
公共静态类结构编辑器
{
公共静态无效编辑(参考结构)
其中TEditor:IStructEditor,new()
{
新的TEditor()
.EditStuct(参考文献s);
}
}
公共接口结构编辑器
{
无效编辑(参考T s);
}
结构成本结构
{
公共成本;
}
类别设置成本
:IStructEditor
{
公共无效编辑结构(参考成本结构)
{
s、 成本=123;
}
}
因此,您可以按如下方式使用它:
CostStruct s = new CostStruct();
StructEditor.Edit<CostStruct, SetCost>(ref s);
CostStruct s=new CostStruct();
StructEditor.Edit(参考s);
这意味着您可以通过实现IStructEditor
快速定义新行为 可能有帮助的非常小的OO示例-在本示例中,使用IStructEditor
界面封装执行编辑的代码:
public static class StructEditor
{
public static void Edit<TStruct, TEditor>(ref TStruct s)
where TEditor : IStructEditor<TStruct>, new()
{
new TEditor()
.EditStuct(ref s);
}
}
public interface IStructEditor<T>
{
void EditStuct(ref T s);
}
struct CostStruct
{
public int Cost;
}
class SetCost
: IStructEditor<CostStruct>
{
public void EditStuct(ref CostStruct s)
{
s.Cost = 123;
}
}
公共静态类结构编辑器
{
公共静态无效编辑(参考结构)
其中TEditor:IStructEditor,new()
{
新的TEditor()
.EditStuct(参考文献s);
}
}
公共接口结构编辑器
{
无效编辑(参考T s);
}
结构成本结构
{
公共成本;
}
类别设置成本
:IStructEditor
{
公共无效编辑结构(参考成本结构)
{
s、 成本=123;
}
}
因此,您可以按如下方式使用它:
CostStruct s = new CostStruct();
StructEditor.Edit<CostStruct, SetCost>(ref s);
CostStruct s=new CostStruct();
StructEditor.Edit(参考s);
这意味着您可以通过实现IStructEditor
快速定义新行为如果你能为你的结构找到一个通用的接口,考虑一下:
class Program
{
static void Main(string[] args)
{
IStruct s1 = new Struct1();
IStruct s2 = new Struct2();
EditStruct(ref s1);
EditStruct(ref s2);
}
static void EditStruct(ref IStruct target)
{
target.Name = Guid.NewGuid().ToString();
}
}
public interface IStruct
{
string Name { get; set; }
}
public struct Struct1 : IStruct
{
public string Name { get; set; }
}
public struct Struct2: IStruct
{
public string Name { get; set; }
}
如果你能为你的结构找到一个通用的接口,考虑一下:
class Program
{
static void Main(string[] args)
{
IStruct s1 = new Struct1();
IStruct s2 = new Struct2();
EditStruct(ref s1);
EditStruct(ref s2);
}
static void EditStruct(ref IStruct target)
{
target.Name = Guid.NewGuid().ToString();
}
}
public interface IStruct
{
string Name { get; set; }
}
public struct Struct1 : IStruct
{
public string Name { get; set; }
}
public struct Struct2: IStruct
{
public string Name { get; set; }
}
下面是一个使用反射的简单解决方案。在这种情况下,反射结果可以很好地缓存,性能影响应该不会那么糟糕
class Program
{
static void Main(string[] args)
{
var x = new Struct1() { A = 0, B = -10 };
var y = new Struct2() { C = 0, D = -10 };
MyFunction(ref x);
MyFunction(ref y);
}
public static void EditStruct(ref Struct1 structToEdit)
{
structToEdit = new Struct1() { A = 10, B = 20 };
}
public static void EditStruct(ref Struct2 structToEdit)
{
structToEdit = new Struct2() { C = 30, D = 40 };
}
private delegate void EditDelegate<T>(ref T obj);
public static void MyFunction<T>(ref T unknownStruct)
{
Delegate d;
if (!_dict.TryGetValue(typeof(T), out d))
{
d = typeof(Program).Assembly.GetTypes()
.SelectMany(x => x.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly))
.Single(x => x.Name == "EditStruct" && x.GetParameters().SingleOrDefault(y => y.ParameterType.Equals(typeof(T).MakeByRefType())) != null)
.CreateDelegate(typeof(EditDelegate<T>));
_dict.Add(typeof(T), d);
}
(d as EditDelegate<T>)(ref unknownStruct);
}
private static readonly Dictionary<Type, Delegate> _dict = new Dictionary<Type, Delegate>(new TypeComparer());
class TypeComparer : IEqualityComparer<Type>
{
public bool Equals(Type x, Type y) => x.Equals(y);
public int GetHashCode(Type obj) => obj.GetHashCode();
}
}
public struct Struct1
{
public int A;
public int B;
}
public struct Struct2
{
public int C;
public int D;
}
类程序
{
静态void Main(字符串[]参数)
{
var x=newstruct1(){A=0,B=-10};
var y=newstruct2(){C=0,D=-10};
MyFunction(参考文献x);
MyFunction(参考文献y);
}
公共静态void EditStruct(参考Struct1 structToEdit)
{
structToEdit=newstruct1(){A=10,B=20};
}
公共静态void EditStruct(参考Struct2 structToEdit)
{
structToEdit=newstruct2(){C=30,D=40};
}
私人代表无效编辑代表(参考T obj);
公共静态void MyFunction(ref T unknownStruct)
{
d代表;
如果(!_dict.TryGetValue(类型(T),输出d))
{
d=typeof(Program.Assembly.GetTypes())
.SelectMany(x=>x.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly))
.Single(x=>x.Name==“EditStruct”&&x.GetParameters().SingleOrDefault(y=>y.ParameterType.Equals(typeof(T).MakeByRefType())!=n