C# 使用预定义类型调用构造函数时动态设置类型
我目前正在努力创建一个公共属性,但类型是在调用构造函数时定义的 这是我现在的代码: 如果它说C# 使用预定义类型调用构造函数时动态设置类型,c#,asp.net,C#,Asp.net,我目前正在努力创建一个公共属性,但类型是在调用构造函数时定义的 这是我现在的代码: 如果它说在这里键入,我应该使用动态还是对象还是什么?我将从外部(公共)访问它,我只有一个简单的ToString()方法,它将使用StringWriter和htmltextwitter解析它,将其作为HTML字符串 我使用的是ASP.NET(不是MVC),所以,我选择什么是性能问题吗?如果我选择对象类型,我仍然可以访问开关内每个对象上的方法吗 我想对这个类做一个new,定义它将创建的元素类型,这样我就可以使用所选
在这里键入
,我应该使用动态
还是对象
还是什么?我将从外部(公共)访问它,我只有一个简单的ToString()
方法,它将使用StringWriter
和htmltextwitter
解析它,将其作为HTML字符串
我使用的是ASP.NET(不是MVC),所以,我选择什么是性能问题吗?如果我选择对象
类型,我仍然可以访问开关
内每个对象上的方法吗
我想对这个类做一个new
,定义它将创建的元素类型,这样我就可以使用所选类的一些方法来设置。例如,如果我选择HtmlInputRadioButton
,我可以使用.Checked
,但我将在其他类中使用此元素,用于设置属性,具体取决于您创建的元素。我明白了吗
一种可能的解决方案是为每种类型创建变量,但使用属性查看哪种类型不为null,并获取该类型,但这不是一种优雅的解决方案
另一个解决方案是使用泛型,其中T:HtmlControls,new(),但我希望用户不要知道,我希望他只编写
new(type.WHICH-to-use)
谢谢大家 公共类clsHtml
public enum Types { Section, Input, File, Radio, Checkbox, Select };
// Why did you decide it to be IDisposable? What are you going to dispose?
public class clsHtml: IDisposable
{
public HtmlControl element { get; private set; }
public clsHtml(Types type)
{
this.CreateElement(type);
}
private void CreateElement(Types type)
{
switch(type)
{
case Types.Input:
this.element = new HtmlInputText();
break;
case Types.File:
this.element = new HtmlInputFile();
break;
case Types.Radio:
this.element = new HtmlInputRadioButton();
break;
case Types.Checkbox:
this.element = new HtmlInputCheckBox();
break;
case Types.Select:
this.element = new HtmlSelect();
break;
default:
throw new NotImplementedException(type.ToString() + " not yet supported!");
}
}
public override string ToString()
{
System.IO.StringWriter writer = new System.IO.StringWriter();
HtmlTextWriter html = new HtmlTextWriter(writer);
this.element.RenderControl(html);
return writer.ToString();
}
}
var clsHtml = new clsHtml(Types.Input);
// the following part sucks, but you don't want to use generics
if (clsHtml.element is HtmlInputText)
{
HtmlInputText elementAsHtmlInputText = clsHtml.element as HtmlInputText;
}
else if ( ...)
...
其中T:HtmlControl,new()
{
公共T元素;
公共clsHtml()
{
元素=新的T();
}
公共重写字符串ToString()
{
System.IO.StringWriter writer=新的System.IO.StringWriter();
HtmlTextWriter html=新的HtmlTextWriter(编写器);
元素。RenderControl(html);
返回writer.ToString();
}
}
这个怎么样?我也这么认为,但是我是否能够访问类中的任何方法,而不是继承的方法?如果我创建
HtmlInputText
但我使用私有HtmlControl元素
我是否能够访问HtmlInputText
上的所有内容?我现在不能测试任何代码,所以这就是为什么我问而不测试,不管怎样,这是关于C#的更基本的东西,我不习惯,你正在为我清除它,谢谢!当然不是。但是你说你只想在它上面做.ToString()
。是的,但是我会定义每个类附带的一些东西,例如在HtmlInputRadioButton
中,我可以使用。选中了,但是如果我定义HtmlControl
我将无法使用它。我说得对吗?是否应该使用动态?问题是“何时”。在将其放入HtmlControl
之前,可以在开关中执行此操作。一旦装箱(即,当您离开开关时),您就不再明确知道类型是什么(隐式地,您可以类型嗅探它)。@P0lT10n在面向对象编程中应尽可能避免强制转换。如果您使用C#编写代码,那么您应该以一种由编译器执行类型安全而不是绕过的方式编写代码。目前,您正试图绕过该语言中的任何良好实践和安全性。这只会导致难以维护和理解的糟糕代码。在编写此类代码之前,您确实应该了解更多关于面向对象编程和编写可靠代码的知识。您不应该尝试模仿无类型语言…我以前已经这样做过,但是任何使用此解决方案的开发人员都必须指定类型,我希望他们在我的代码上的enum
之间进行选择,这样更容易。。。也许使用像这样的泛型和另一个类,我可以通过发送所选的枚举值并使用泛型创建它并返回它来实现这一点?我想避免开发人员明确地编写类型,这样对他们来说更容易,他们只能选择一个预定义的可用类型。如果我能够使用我说的,IntelliSense将非常有用,这就是为什么。我知道它存在,但它有所有可能的标记,而不是我预先选择的标记,你说它是什么意思,要在哪里使用它?IntelliSense也存在,只需键入System.Web.UI.HtmlControls
OK。现在有一种方法可以知道这个类之外的类型,而无需强类型(就像我提供的泛型一样)。似乎您必须使用我的另一种解决方案,您的类之外的使用者必须在强制转换后检查元素的类型,并对其执行任何他们想要的操作。使用基类HtmlControl
或类似于返回类型的东西,并将其强制转换为调用代码上的正确类型如何?这对你不管用吗?我不知道你在说什么,我对演员几乎一无所知:S我想我看过一次。。。你能再解释一下吗?当然。这是一个基本的例子,因为我不确定你所说的用户不应该知道的意思var htmlEle=new clsHtml(Types Radio)
现在在调用代码上,尝试htmlEle.getType()
,它将返回HtmlInputRadioButton
并将其强制转换回该类型,以使用该类型固有的方法。意思是var radioBtn=(HtmlInputRadioButton)htmlEle
然后radioBtn.Checked
((在SWITCH中创建的实数类型)clsHTML.element)。该类型的任何方法都不能写入任何内容,而只能在此处键入类型安全、支持IntelliSense并允许访问特定成员的。如果使用dynamic,则没有IntelliSense,并且在运行时之前不会检查属性是否存在。如果使用对象
,则只能访问几个标准方法。如果使用HtmlControl
,则每次需要执行特定操作时都必须检查类型。在这种情况下,使用Enum
没有任何用处。如果你真的想要那种代码,
public enum Types { Section, Input, File, Radio, Checkbox, Select };
// Why did you decide it to be IDisposable? What are you going to dispose?
public class clsHtml: IDisposable
{
public HtmlControl element { get; private set; }
public clsHtml(Types type)
{
this.CreateElement(type);
}
private void CreateElement(Types type)
{
switch(type)
{
case Types.Input:
this.element = new HtmlInputText();
break;
case Types.File:
this.element = new HtmlInputFile();
break;
case Types.Radio:
this.element = new HtmlInputRadioButton();
break;
case Types.Checkbox:
this.element = new HtmlInputCheckBox();
break;
case Types.Select:
this.element = new HtmlSelect();
break;
default:
throw new NotImplementedException(type.ToString() + " not yet supported!");
}
}
public override string ToString()
{
System.IO.StringWriter writer = new System.IO.StringWriter();
HtmlTextWriter html = new HtmlTextWriter(writer);
this.element.RenderControl(html);
return writer.ToString();
}
}
var clsHtml = new clsHtml(Types.Input);
// the following part sucks, but you don't want to use generics
if (clsHtml.element is HtmlInputText)
{
HtmlInputText elementAsHtmlInputText = clsHtml.element as HtmlInputText;
}
else if ( ...)
...
public class clsHtml<T>
where T : HtmlControl, new()
{
public T element;
public clsHtml()
{
element = new T();
}
public override string ToString()
{
System.IO.StringWriter writer = new System.IO.StringWriter();
HtmlTextWriter html = new HtmlTextWriter(writer);
element.RenderControl(html);
return writer.ToString();
}
}