我有:
class Car {..}
class Other{
List<T> GetAll(){..}
}
Run Code Online (Sandbox Code Playgroud)
我想要做:
Type t = typeof(Car);
List<t> Cars = GetAll<t>();
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
我想从运行时使用反射发现的类型的数据库中返回一个泛型集合.
假设我有一个无约束的泛型方法,适用于支持相等的所有类型.它执行成对等式检查,因此适用于O(n 2):
public static int CountDuplicates<T>(IList<T> list)
{
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
我还有一个约束泛型方法,只适用于支持排序的类型.它从O(n log n)中的列表排序开始,然后在一次传递中计算所有重复项:
public static int CountDuplicatesFast<T>(IList<T> list)
where T : IComparable<T>
{
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
因此,如果静态地知道列表的元素类型支持排序,则调用者可以选择调用快速方法.可能会发生调用者本身使用泛型IList<T>,其中T不受约束,因此它是调用第一个(慢)方法的唯一选项.
现在,我希望第一个方法在运行时检查类型是否T实际实现了接口IComparable<T>,如果是,则调用fast方法:
public static int CountDuplicates<T>(IList<T> list)
{
if (typeof(IComparable<T>).IsAssignableFrom(typeof(T)))
{
return CountDuplicatesFast(list);
}
else
{
/* use the slow algorithm */
}
}
Run Code Online (Sandbox Code Playgroud)
问题是编译器拒绝调用CountDuplicatesFast(list):
错误CS0314:类型'T'不能用作泛型类型或方法'Program.CountDuplicatesFast <T>(System.Collections.Generic.IList <T>)'中的类型参数'T'.从'T'到'System.IComparable <T>'没有装箱转换或类型参数转换.
是否有可能说服编译器相信我,我知道我在做什么,并跳过约束检查?
通用方法是......
public void PrintGeneric2<T>(T test) where T : ITest
{
Console.WriteLine("Generic : " + test.myvar);
}
Run Code Online (Sandbox Code Playgroud)
我是从Main()调用它的...
Type t = test2.GetType();
PrintGeneric2<t>(test2);
Run Code Online (Sandbox Code Playgroud)
我得到错误"CS0246:类型或命名空间名称'T’无法找到"和"CS1502:最好重载的方法匹配DoSomethingClass.PrintGeneric2 <T>(T)具有无效参数"
这与我之前的问题有关:C#:传递通用对象
我已经读过,在没有使用反射或methodinfo的情况下,无法在运行时确定泛型类型,但是在这个实例中我不太清楚如何这样做.
谢谢,如果你能启发我=)
我的DataAccessLayer上有一个FindAll方法,如下所示:
public FindResult<T> FindAll<T>() where T : Entity, new()
Run Code Online (Sandbox Code Playgroud)
和一个客户端代码有一个Type []数组,它需要用来迭代调用FindAll方法,如下所示:
foreach (var type in typeArray)
{
var result = DataAccessLayer.FindAll<type>();
...
Run Code Online (Sandbox Code Playgroud)
但是编译器抱怨"预期的类型或命名空间"..有没有一种简单的方法来解决这个问题?我尝试过type.GetType()或typeof(type),但都没有用.
提前谢谢了!
随着讨论这里,C#不支持通用属性的声明.所以,我不允许做类似的事情:
[Audit<User> (UserAction.Update)]
public ActionResult SomeMethod(int id){ ...
Run Code Online (Sandbox Code Playgroud)
这就像我的属性impl类中的魅力一样,因为我需要从通用存储库中调用一个方法:
User fuuObj = (User) repository.LoadById<T>(_id);
Run Code Online (Sandbox Code Playgroud)
我尝试使用此解决方案但没有成功.我可以通过类似的东西typeOf(User),但我怎么能用LoadById类型或魔术字符串调用?
*T和User都扩展了一个名为Entity的基类.
我有类似的东西
Type MyType = Type.GetType(FromSomewhereElse);
var listS = context.GetList<MyType>().ToList();
Run Code Online (Sandbox Code Playgroud)
我希望在这种情况下获取MyType,并将其传递给Generic Type方法GetList
这是我得到的错误:
找不到类型或命名空间名称"MyType"(您是否缺少using指令或程序集引用?)
执行以下代码时,我收到此错误"无法对ContainsGenericParameters为true的类型或方法执行后期绑定操作."
class Program
{
static void Main(string[] args)
{
MethodInfo MI = typeof(MyClass).GetMethod("TestProc");
MI.MakeGenericMethod(new [] {typeof(string)});
MI.Invoke(null, new [] {"Hello"});
}
}
class MyClass
{
public static void TestProc<T>(T prefix)
{
Console.WriteLine("Hello");
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码只是我面临的实际问题的缩放版本.请帮忙.
我正在为类构造函数编写一些代码,它循环遍历类的所有属性,并调用一个通用的静态方法,该方法使用外部API中的数据填充我的类.所以我把它作为一个示例类:
public class MyClass{
public string Property1 { get; set; }
public int Property2 { get; set; }
public bool Property3 { get; set; }
public static T DoStuff<T>(string name){
// get the data for the property from the external API
// or if there's a problem return 'default(T)'
}
}
Run Code Online (Sandbox Code Playgroud)
现在在我的构造函数中我想要这样的东西:
public MyClass(){
var properties = this.GetType().GetProperties();
foreach(PropertyInfo p in properties){
p.SetValue(this, DoStuff(p.Name), new object[0]);
}
}
Run Code Online (Sandbox Code Playgroud)
所以上面的构造函数会抛出一个错误,因为我没有提供泛型类型.
那么如何传入属性的类型呢?
我目前正面临C#中的问题,我认为可以使用存在类型来解决.但是,我真的不知道它们是可以用C#创建还是模拟(使用其他构造).
基本上我想要一些像这样的代码:
public interface MyInterface<T>
{
T GetSomething();
void DoSomething(T something);
}
public class MyIntClass : MyInterface<int>
{
int GetSomething()
{
return 42;
}
void DoSomething(int something)
{
Console.Write(something);
}
}
public class MyStringClass : MyInterface<string>
{
string GetSomething()
{
return "Something";
}
void DoSomething(string something)
{
SomeStaticClass.DoSomethingWithString(something);
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,我希望能够遍历实现此接口的对象列表,但不关心它具有什么类型参数.像这样的东西:
public static void DoALotOfThingsTwice(){
var listOfThings = new List<MyInterface<T>>(){
new MyIntClass(),
new MyStringClass();
};
foreach (MyInterface<T> thingDoer in listOfThings){
T something = thingDoer.GetSomething();
thingDoer.DoSomething(something);
thingDoer.DoSomething(something);
}
}
Run Code Online (Sandbox Code Playgroud)
这不会编译,因为T …
这是上下文:
我尝试编写一个映射器,用于动态地将我的DomainModel对象转换为ViewModel Ojects.我得到的问题是,当我尝试通过反射调用泛型类的方法时,我得到了这个错误:
System.InvalidOperationException:无法对ContainsGenericParameters为true的类型或方法执行后期绑定操作.
有人可以帮助我找出错误在哪里吗?这将不胜感激
这是代码(我试图简化它):
public class MapClass<SourceType, DestinationType>
{
public string Test()
{
return test
}
public void MapClassReflection(SourceType source, ref DestinationType destination)
{
Type sourceType = source.GetType();
Type destinationType = destination.GetType();
foreach (PropertyInfo sourceProperty in sourceType.GetProperties())
{
string destinationPropertyName = LookupForPropertyInDestinationType(sourceProperty.Name, destinationType);
if (destinationPropertyName != null)
{
PropertyInfo destinationProperty = destinationType.GetProperty(destinationPropertyName);
if (destinationProperty.PropertyType == sourceProperty.PropertyType)
{
destinationProperty.SetValue(destination, sourceProperty.GetValue(source, null), null);
}
else
{
Type d1 = typeof(MapClass<,>);
Type[] typeArgs = { destinationProperty.GetType(), sourceType.GetType() };
Type constructed = …Run Code Online (Sandbox Code Playgroud) c# ×10
generics ×9
reflection ×6
.net ×4
asp.net-mvc ×1
casting ×1
clr ×1
constraints ×1
polymorphism ×1
runtime ×1
types ×1