Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#-从参数类型未知的函数调用良好的重载方法_C#_Generics_Dynamic_Struct_Reference - Fatal编程技术网

c#-从参数类型未知的函数调用良好的重载方法

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

我试图从参数类型未知的函数调用良好的重载方法。但我总是有一个转换错误。 我怎么能这样做

Ps我尝试不使用if来检查类型

我试图将我的函数更改为泛型,但我遇到了一个转换错误

"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