如何在我的InstantiateType<T>方法中实例化类型T ?
我收到错误:'T'是'类型参数'但是像'变量'一样使用.:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestGeneric33
{
class Program
{
static void Main(string[] args)
{
Container container = new Container();
Console.WriteLine(container.InstantiateType<Customer>("Jim", "Smith"));
Console.WriteLine(container.InstantiateType<Employee>("Joe", "Thompson"));
Console.ReadLine();
}
}
public class Container
{
public T InstantiateType<T>(string firstName, string lastName) where T : IPerson
{
T obj = T();
obj.FirstName(firstName);
obj.LastName(lastName);
return obj;
}
}
public interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
public class Customer : IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Company { get; set; }
}
public class Employee : IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int EmployeeNumber { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
感谢所有评论,他们让我走上正轨,这就是我想要做的:
using System;
namespace TestGeneric33
{
class Program
{
static void Main(string[] args)
{
Container container = new Container();
Customer customer1 = container.InstantiateType<Customer>("Jim", "Smith");
Employee employee1 = container.InstantiateType<Employee>("Joe", "Thompson");
Console.WriteLine(PersonDisplayer.SimpleDisplay(customer1));
Console.WriteLine(PersonDisplayer.SimpleDisplay(employee1));
Console.ReadLine();
}
}
public class Container
{
public T InstantiateType<T>(string firstName, string lastName) where T : IPerson, new()
{
T obj = new T();
obj.FirstName = firstName;
obj.LastName = lastName;
return obj;
}
}
public interface IPerson
{
string FirstName { get; set; }
string LastName { get; set; }
}
public class PersonDisplayer
{
private IPerson _person;
public PersonDisplayer(IPerson person)
{
_person = person;
}
public string SimpleDisplay()
{
return String.Format("{1}, {0}", _person.FirstName, _person.LastName);
}
public static string SimpleDisplay(IPerson person)
{
PersonDisplayer personDisplayer = new PersonDisplayer(person);
return personDisplayer.SimpleDisplay();
}
}
public class Customer : IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Company { get; set; }
}
public class Employee : IPerson
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int EmployeeNumber { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
Joe*_*orn 113
像这样声明你的方法:
public string InstantiateType<T>(string firstName, string lastName)
where T : IPerson, new()
Run Code Online (Sandbox Code Playgroud)
注意最后的附加约束.然后new在方法体中创建一个实例:
T obj = new T();
Run Code Online (Sandbox Code Playgroud)
ann*_*ata 28
几种方式.
没有指定类型必须有一个构造函数:
T obj = default(T); //which will produce null for reference types
Run Code Online (Sandbox Code Playgroud)
使用构造函数:
T obj = new T();
Run Code Online (Sandbox Code Playgroud)
但这要求条款:
where T : new()
Run Code Online (Sandbox Code Playgroud)
Dan*_* C. 13
为了扩展上面的答案,向where T:new()泛型方法添加约束将要求T具有公共的无参数构造函数.
如果你想避免这种情况 - 并且在工厂模式中你有时强迫其他人通过你的工厂方法而不是直接通过构造函数 - 那么替代方法是使用reflection(Activator.CreateInstance...)并保持默认构造函数为private.但这当然会带来性能损失.
有点旧但对于其他寻求解决方案的人来说,也许这可能会引起兴趣:http : //daniel.wertheim.se/2011/12/29/c-generic-factory-with-support-for-private-constructors/
两种解决方案。一种使用 Activator,一种使用 Compiled Lambdas。
//Person has private ctor
var person = Factory<Person>.Create(p => p.Name = "Daniel");
public static class Factory<T> where T : class
{
private static readonly Func<T> FactoryFn;
static Factory()
{
//FactoryFn = CreateUsingActivator();
FactoryFn = CreateUsingLambdas();
}
private static Func<T> CreateUsingActivator()
{
var type = typeof(T);
Func<T> f = () => Activator.CreateInstance(type, true) as T;
return f;
}
private static Func<T> CreateUsingLambdas()
{
var type = typeof(T);
var ctor = type.GetConstructor(
BindingFlags.Instance | BindingFlags.CreateInstance |
BindingFlags.NonPublic,
null, new Type[] { }, null);
var ctorExpression = Expression.New(ctor);
return Expression.Lambda<Func<T>>(ctorExpression).Compile();
}
public static T Create(Action<T> init)
{
var instance = FactoryFn();
init(instance);
return instance;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
51473 次 |
| 最近记录: |