如果BaseFruit有一个接受一个的构造函数,int weight我可以用这样的泛型方法实例化一块水果吗?
public void AddFruit<T>()where T: BaseFruit{
BaseFruit fruit = new T(weight); /*new Apple(150);*/
fruit.Enlist(fruitManager);
}
Run Code Online (Sandbox Code Playgroud)
注释后面添加了一个示例.如果我给出BaseFruit一个无参数构造函数然后通过成员变量填充所有内容,我似乎只能这样做.在我的真实代码中(不是关于水果),这是不切实际的.
-Update-
所以它似乎无法以任何方式通过约束来解决.从答案中有三种候选解决方案:
我倾向于认为反射是最不干净的,但我不能在其他两个之间做出决定.
我有一个泛型类,我想用泛型类型实例化一个对象.我想为类型的构造函数使用一个参数.
我的代码:
public class GenericClass<T> where T : Some_Base_Class, new()
{
public static T SomeFunction(string s)
{
if (String.IsNullOrEmpty(s))
return new T(some_param);
}
}
Run Code Online (Sandbox Code Playgroud)
我得到了一个错误
new T(some_param)
Run Code Online (Sandbox Code Playgroud)
'T':在创建变量类型的实例时无法提供参数
任何想法我怎么能这样做?
System.Activator.CreateInstance(T)方法是否有性能问题(因为我怀疑它使用反射)大到足以阻止我们随便使用它?
我正在尝试创建一个泛型类,其中new是泛型类的实例.如下:
public class HomepageCarousel<T> : List<T>
where T: IHomepageCarouselItem, new()
{
private List<T> GetInitialCarouselData()
{
List<T> carouselItems = new List<T>();
if (jewellerHomepages != null)
{
foreach (PageData pageData in jewellerHomepages)
{
T item = new T(pageData); // this line wont compile
carouselItems.Add(item);
}
}
return carouselItems;
}
}
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
在创建变量类型的实例时无法提供参数
我发现了以下与我需要的相关的问题:将 参数传递给模板化类型的C#generic new()
但是,我不能使用Jared建议的答案,因为我在Generic类中调用方法,而不是在它之外,所以我不能指定具体的类.
有没有解决的办法?
我已根据另一个问题尝试了以下内容,但它不起作用,因为我不知道要指定的具体类型.从泛型类中调用它,而不是在外面调用:
public class HomepageCarousel<T> : List<T>
where T: IHomepageCarouselItem, new()
{
private List<T> LoadCarouselItems()
{
if (IsCarouselConfigued)
{
return GetConfiguredCarouselData();
}
// ****** I don't …Run Code Online (Sandbox Code Playgroud) 我想知道为什么泛型类型参数的新约束只能在没有参数的情况下应用,也就是说,可以将类型约束为具有无参数构造函数,但是不能将类约束为具有构造函数,接收一个int作为参数.我知道这方面的方法,使用反射或工厂模式,工作正常,好吧.但我真的很想知道为什么,因为我一直在思考它,我真的想不出无参数构造函数和带有参数的区别,这些参数可以证明对新约束的这种限制.我错过了什么?非常感谢
@Eric:让我和你在一起一会儿:
构造函数是方法
那么我想如果我这样做,没有人会反对:
public interface IReallyWonderful
{
new(int a);
string WonderMethod(int a);
}
Run Code Online (Sandbox Code Playgroud)
但是一旦我有了,那我就去:
public class MyClass<T>
where T : IReallyWonderful
{
public string MyMethod(int a, int b)
{
T myT = new T(a);
return myT.WonderMethod(b);
}
}
Run Code Online (Sandbox Code Playgroud)
这首先是我想要做的.所以,抱歉,但不,构造函数不是方法,或者至少不完全.
关于实现这个功能的困难,我真的不知道,即使我这样做了,我对于明智地支出股东资金的决定也没什么可说的.这样的话,我会马上把它标记为答案.
从学术(我)的角度来看,也就是说,没有任何关于实施成本的问题,问题确实是(我在最近几个小时内完成了这个问题):
构造函数应该被视为类的实现的一部分,还是作为语义契约的一部分(以同样的方式将接口视为语义契约).
如果我们将构造函数视为实现的一部分,那么,约束泛型类型参数的构造函数不是一件非常通用的事情,因为这会将你的泛型类型绑定到具体的实现,并且几乎可以说为什么完全使用泛型?
作为实现的一部分的构造函数的示例(在指定任何下面的构造函数作为定义的语义契约的一部分时没有意义ITransformer):
public interface ITransformer
{
//Operates with a and returns the result;
int Transform(int a);
}
public class PlusOneTransformer : ITransformer
{
public int Transform(int a)
{
return a …Run Code Online (Sandbox Code Playgroud) 目前,我使用的是这样的:
try
{
dr = SQL.Execute(sql);
if(dr != null) {
while(dr.Read()) {
CustomObject c = new CustomObject();
c.Key = dr[0].ToString();
c.Value = dr[1].ToString();
c.Meta = dr[2].ToString();
customerInfo.CustomerList.Add(c);
}
}
else
{
customerInfo.ErrorDetails="No records found";
}
Run Code Online (Sandbox Code Playgroud)
而不是我手动执行分配,有没有办法直接执行此映射(假设列名称与字段名称匹配).
然而,一个要求是我希望通过我当前使用sql查询的方法而不是使用基于纯LINQ的方法来实现这一点.首先,SQL查询足够大,涉及复杂的JOIN并且已经过彻底测试,因此我不想在此时引入更多错误.有什么建议?
在我的软件中有这种常见模式,其中完成数据库查询并从该查询创建对象列表,其中对象是从a构造的SqlDataReader.
例如:
public List<Authorization> ReadAuthorizations() {
List<Authorization> authorizations = new List<Authorization>();
using (SqlConnection connection = GetConnection(mConnString)) {
using (SqlDataReader authReader = CmdFactory.Instance.ReadAuthorizations(connection)) {
while (authReader.Read()) {
Authorization auth = new Authorization(authReader);
authorizations.Add(auth);
}
}
}
return authorizations;
}
Run Code Online (Sandbox Code Playgroud)
您可以替换Authorization任何类型的对象,但每次都是相同的模式.唯一的变量是对象类型和用于查询数据库的函数.
List<Authorization> ReadAuthorizations()
List<Login> ReadLogins()
List<Batch> ReadBatches()
// etc
Run Code Online (Sandbox Code Playgroud)
现在我觉得这只是为一个通用功能而尖叫,我想出了这个:
public List<T> Read<T>(Func<SqlConnection, SqlDataReader> func) where T : new()
{
List<T> objects = new List<T>();
using (SqlConnection connection = GetConnection(_ropsString))
{
using (SqlDataReader reader = func(connection))
{
while …Run Code Online (Sandbox Code Playgroud) 我有一个辅助函数来从XML获取值,它可以正常使用像int这样的值类型和字符串.我还有一些类将XPathNavigator作为其构造函数中的参数,我想做类似以下的事情:
public static void SelectSingleNodeSafe<T>(XPathNavigator nav, string pos, out T ret, T def)
{
XPathNavigator node = nav.SelectSingleNode(pos);
if (node != null)
if (typeof(T).IsSubclassOf(XMLConstructible))
ret = new T(node);// this won't compile
else
ret = (T)node.ValueAs(typeof(T));//this works for my use cases
else
ret = def;
}
Run Code Online (Sandbox Code Playgroud)
有遗嘱但有办法吗?
我有一个采用T类型的通用方法,我需要能够在需要单个XmlNode的情况下调用构造函数。当前,我正在尝试通过具有一个抽象基类来实现此目的,该基类具有我想要的构造函数(加上一个无参数的构造函数,因此除了添加实际的子类之外,我无需编辑“子类”)并以此进行约束。如果我尝试实例化这些类之一,它会抱怨:
Cannot create an instance of the variable type 'T' because it does not have the new() constraint
Run Code Online (Sandbox Code Playgroud)
如果我添加new()约束,我得到:
'T': cannot provide arguments when creating an instance of a variable type
Run Code Online (Sandbox Code Playgroud)
我该怎么办?
我试图弄清楚如何在C#中使用模板。我这样写:
public static List<TValue> deepCopyList<TValue>(List<TValue> src)
{
List<TValue> arr = new List<TValue>();
for (int i = 0; i < src.Count; i++)
{
arr.Add(new TValue(src[i])); //Error on this line
}
return arr;
}
Run Code Online (Sandbox Code Playgroud)
但是我得到一个错误:
错误CS0304:无法创建变量类型'TValue'的实例,因为它没有new()约束
c# ×9
generics ×7
.net ×4
activator ×1
constraints ×1
list ×1
new-operator ×1
performance ×1
sql ×1
templates ×1