Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.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# 通过通用的<;TObject>;课改成表格_C#_Forms_Generic Programming_Tobject - Fatal编程技术网

C# 通过通用的<;TObject>;课改成表格

C# 通过通用的<;TObject>;课改成表格,c#,forms,generic-programming,tobject,C#,Forms,Generic Programming,Tobject,我似乎无法通过搜索找到答案,因此 我知道,通过使用以下类型的代码,我可以将类对象一般地传递给其他类: public class ClsGeneric<TObject> where TObject : class { public TObject GenericType { get; set; } } public class ClsGeneric其中TObject:class { 公共对象泛型{get;set;} } 然后以这种方式构建: ClsGeneric<My

我似乎无法通过搜索找到答案,因此

我知道,通过使用以下类型的代码,我可以将类对象一般地传递给其他类:

public class ClsGeneric<TObject> where TObject : class
{
    public TObject GenericType { get; set; }
}
public class ClsGeneric其中TObject:class
{
公共对象泛型{get;set;}
}
然后以这种方式构建:

ClsGeneric<MyType> someName = new ClsGeneric<MyType>()
ClsGeneric someName=new ClsGeneric()
但是,我有一个应用程序,它要求我打开一个表单,并以某种方式传递泛型类型以在该表单中使用。我正在尝试将此表单重新用于许多不同的类类型

有人知道这是否可能,如果有,怎么做

我已经尝试了一些表单构造函数,但是没有用

多谢各位, 戴夫

更新:澄清我试图达到的结果是什么

更新:8月4日,我又前进了一步,但我为这个解决方案提供了一笔奖金。以下是我现在拥有的:

interface IFormInterface
{
    DialogResult ShowDialog();
}


public class FormInterface<TObject> : SubForm, IFormInterface where TObject : class
{ }

public partial class Form1 : Form
{
    private FormController<Parent> _formController;

    public Form1()
    {
        InitializeComponent();
            _formController = new FormController<Parent>(this.btnShowSubForm, new DataController<Parent>(new MeContext()));   
    }
}

public class FormController<TObject> where TObject : class
{
    private DataController<TObject> _dataController;
    public FormController(Button btn, DataController<TObject> dataController)
    {
        _dataController = dataController;
        btn.Click += new EventHandler(btnClick);
    }

    private void btnClick(object sender, EventArgs e)
    {
        showSubForm("Something");
    }

    public void showSubForm(string className)
    {
        //I'm still stuck here because I have to tell the interface the Name of the Class "Child", I want to pass <TObject> here.
        // Want to pass in the true Class name to FormController from the MainForm only, and from then on, it's generic.

        IFormInterface f2 = new FormInterface<Child>();
        f2.ShowDialog();
    }
}

class MeContext : DbContext
{
    public MeContext() : base(@"data source=HAZEL-PC\HAZEL_SQL;initial catalog=MCL;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework") { }
    public DbSet<Parent> Child { get; set; }
}

public class DataController<TObject> where TObject : class
{
    protected DbContext _context;

    public DataController(DbContext context)
    {
        _context = context;
    }
}

public class Parent
{
    string Name { get; set; }
    bool HasChildren { get; set; }
    int Age { get; set; }
}

public class Child
{
    string Name { get; set; }
    int Age { get; set; }
}
接口
{
DialogResult ShowDialog();
}
接口的公共类:子窗体,其中ToObject:class的接口
{ }
公共部分类Form1:Form
{
专用FormController _FormController;
公共表格1()
{
初始化组件();
_formController=new formController(this.btnShowSubForm,new DataController(new MeContext());
}
}
公共类FormController,其中TObject:class
{
专用数据控制器DataController;
公共表单控制器(按钮btn、数据控制器DataController)
{
_数据控制器=数据控制器;
点击+=新建事件处理程序(点击);
}
私有void btnClick(对象发送方,事件参数e)
{
显示子窗体(“某物”);
}
public void showSubForm(字符串类名称)
{
//我仍然被困在这里,因为我必须告诉接口类“Child”的名称,我想传递到这里。
//只想从MainForm向FormController传递真正的类名,从那时起,它就是泛型的。
IFormInterface f2=新的FormInterface();
f2.ShowDialog();
}
}
类MeContext:DbContext
{
public MeContext():base(@“数据源=HAZEL-PC\HAZEL_SQL;初始目录=MCL;集成安全性=True;MultipleActiveResultSets=True;应用程序=EntityFramework”){
公共DbSet子项{get;set;}
}
公共类DataController,其中TObject:class
{
受保护的DbContext\u context;
公共DataController(DbContext上下文)
{
_上下文=上下文;
}
}
公共类父类
{
字符串名称{get;set;}
布尔有子对象{get;set;}
int Age{get;set;}
}
公营儿童
{
字符串名称{get;set;}
int Age{get;set;}
}
尝试工厂方法

public interface IProvider
{
    T GetObject<T>();
}
二级表格:

public class TopLevelForm : Form
{
    public TopLevelForm(IProvider provider):base()
    {
         _provider = provider;
    }

    private void ShowSecondForm()
    {
        var f2 = new SecondForm(provider);
        f2.Show();
    }
}
public class SecondLevelForm : Form
{
    public SecondLevelForm(IProvider provider):base()
    {
         _data = provider.GetObject<MyEntity>();
    }
}
公共类二级表单:表单
{
publicsecondlevelform(IProvider提供程序):base()
{
_data=provider.GetObject();
}
}

至于
IProvider
的实现,有很多方法,从最简单的方法开始,
返回新的T()

也许您已经尝试过,但您可以创建一个自定义类:

public class GenericForm<TObject> : Form where TObject : class
{
    // Here you can do whatever you want,
    // exactly like the example code in the
    // first lines of your question
    public TObject GenericType { get; set; }

    public GenericForm()
    {
        // To show that this actually works,
        // I'll handle the Paint event, because
        // it is executed AFTER the window is shown.
        Paint += GenericForm_Paint;
    }

    private void GenericForm_Paint(object sender, EventArgs e)
    {
        // Let's print the type of TObject to see if it worked:
        MessageBox.Show(typeof(TObject).ToString());
    }
}
在这个例子中,因为我们知道这是一个字符串,所以我们也知道它应该抛出一个异常,因为字符串没有无参数构造函数。因此,让我们改用char数组(
char[]
)构造函数:

GenericType = (TObject)Activator.
         CreateInstance(typeof(TObject), new char[] { 'T', 'e', 's', 't' });

MessageBox.Show(GenericType as string);
结果是:

那我们就做作业吧。下面的代码应该实现您想要做的事情

public class Parent
{
    string Name { get; set; }
    bool HasChildren { get; set; }
    int Age { get; set; }
}

public class Child
{
    string Name { get; set; }
    int Age { get; set; }
}

public class DataController<TObject> where TObject : class
{
    protected DbContext _context;

    public DataController(DbContext context)
    {
        _context = context;
    }
}

public class FormController<TObject> where TObject : class
{
    private DataController<TObject> _dataController;

    public FormController(Button btn, DataController<TObject> dataController)
    {
        _dataController = dataController;
        btn.Click += new EventHandler(btnClick);
    }

    private void btnClick(object sender, EventArgs e)
    {
        GenericForm<TObject> form = new GenericForm<TObject>();
        form.ShowDialog();
    }
}

public class GenericForm<TObject> : Form where TObject : class
{
    public TObject GenericType { get; set; }

    public GenericForm()
    {
        Paint += GenericForm_Paint;
    }

    private void GenericForm_Paint(object sender, EventArgs e)
    {
        MessageBox.Show(typeof(TObject).ToString());

        // If you want to instantiate:
        GenericType = (TObject)Activator.CreateInstance(typeof(TObject));
    }
}
更新 正如RupertMorrish所指出的,您仍然可以编译以下代码:

public class MyObj : IAllowedParamType
{
    public int Id { get; set; }

    public MyObj(int id)
    {
        Id = id;
    }
}
这仍然会引发一个异常,因为您刚刚删除了隐式无参数构造函数。当然,如果您知道自己在做什么,这是很难做到的,但是我们可以通过对“where”类型筛选使用
new()
来禁止这种情况,同时也可以去掉
Activator.CreateInstance
之类的东西

整个代码:

// Maybe you should give a better name to this...
public interface IAllowedParamType { }

// Inherit all the possible classes with that
public class Parent : IAllowedParamType
{
    string Name { get; set; }
    bool HasChildren { get; set; }
    int Age { get; set; }
}

public class Child : IAllowedParamType
{
    string Name { get; set; }
    int Age { get; set; }
}

// Filter the interface on the 'where'
public class DataController<TObject> where TObject : new(), IAllowedParamType
{
    protected DbContext _context;

    public DataController(DbContext context)
    {
        _context = context;
    }
}

public class FormController<TObject> where TObject : new(), IAllowedParamType
{
    private DataController<TObject> _dataController;

    public FormController(Button btn, DataController<TObject> dataController)
    {
        _dataController = dataController;
        btn.Click += new EventHandler(btnClick);
    }

    private void btnClick(object sender, EventArgs e)
    {
        GenericForm<TObject> form = new GenericForm<TObject>();
        form.ShowDialog();
    }
}

public class GenericForm<TObject> : Form where TObject : new(), IAllowedParamType
{
    public TObject GenericType { get; set; }

    public GenericForm()
    {
        Paint += GenericForm_Paint;
    }

    private void GenericForm_Paint(object sender, EventArgs e)
    {
        MessageBox.Show(typeof(TObject).ToString());

        // If you want to instantiate:
        GenericType = new TObject();
    }
}
//也许你应该给它起个更好的名字。。。
公共接口IAllowedParamType{}
//用它继承所有可能的类
公共类父级:IAllowedParamType
{
字符串名称{get;set;}
布尔有子对象{get;set;}
int Age{get;set;}
}
公共类子级:IAllowedParamType
{
字符串名称{get;set;}
int Age{get;set;}
}
//在“何处”上筛选接口
公共类DataController,其中ToObject:new(),IAllowedParamType
{
受保护的DbContext\u context;
公共DataController(DbContext上下文)
{
_上下文=上下文;
}
}
公共类FormController,其中ToObject:new(),IAllowedParamType
{
专用数据控制器DataController;
公共表单控制器(按钮btn、数据控制器DataController)
{
_数据控制器=数据控制器;
点击+=新建事件处理程序(点击);
}
私有void btnClick(对象发送方,事件参数e)
{
GenericForm form=新的GenericForm();
form.ShowDialog();
}
}
公共类GenericForm:Form,其中ToObject:new(),IAllowedParamType
{
公共对象泛型{get;set;}
公共一般形式()
{
油漆+=通用型油漆;
}
私有void GenericForm_Paint(对象发送方,事件参数e)
{
Show(typeof(TObject.ToString());
//如果要实例化:
GenericType=new TObject();
}
}

我认为您可以在
FormController
中添加一个新的类型参数:

public class FormController<TParent, TChild>
  where TParent : class
  where TChild : class 
{
    ...

    public void showSubForm(string className)
    {
        IFormInterface f2 = new FormInterface<TChild>();
        f2.ShowDialog();
    }
}
公共类FormController
地点:班级
孩子:在哪里上课
{
...
public void showSubForm(字符串类名称)
{
IFormInterface f2=新的FormInterface();
f2.ShowDialog();
}
}

据我所知,您希望在
MainForm
中的某个操作中打开
表单
,使用
FormController
作为所有表单的管理器,将泛型类型信息转发给
public class MyObj : IAllowedParamType
{
    public int Id { get; set; }

    public MyObj(int id)
    {
        Id = id;
    }
}
// Maybe you should give a better name to this...
public interface IAllowedParamType { }

// Inherit all the possible classes with that
public class Parent : IAllowedParamType
{
    string Name { get; set; }
    bool HasChildren { get; set; }
    int Age { get; set; }
}

public class Child : IAllowedParamType
{
    string Name { get; set; }
    int Age { get; set; }
}

// Filter the interface on the 'where'
public class DataController<TObject> where TObject : new(), IAllowedParamType
{
    protected DbContext _context;

    public DataController(DbContext context)
    {
        _context = context;
    }
}

public class FormController<TObject> where TObject : new(), IAllowedParamType
{
    private DataController<TObject> _dataController;

    public FormController(Button btn, DataController<TObject> dataController)
    {
        _dataController = dataController;
        btn.Click += new EventHandler(btnClick);
    }

    private void btnClick(object sender, EventArgs e)
    {
        GenericForm<TObject> form = new GenericForm<TObject>();
        form.ShowDialog();
    }
}

public class GenericForm<TObject> : Form where TObject : new(), IAllowedParamType
{
    public TObject GenericType { get; set; }

    public GenericForm()
    {
        Paint += GenericForm_Paint;
    }

    private void GenericForm_Paint(object sender, EventArgs e)
    {
        MessageBox.Show(typeof(TObject).ToString());

        // If you want to instantiate:
        GenericType = new TObject();
    }
}
public class FormController<TParent, TChild>
  where TParent : class
  where TChild : class 
{
    ...

    public void showSubForm(string className)
    {
        IFormInterface f2 = new FormInterface<TChild>();
        f2.ShowDialog();
    }
}