2012-09-07 31 views
1

当条件(pred)对其某个类成员(值)成立时,我想更新对象列表(mycapsule,有许多其他成员)。每当我改变一件事情失败时,我都是C#的新手,真的很困惑。 有人可以解决我的代码: 在最佳状态我只得到得到这个错误,但我觉得很多事情都是在我的代码C#,使用委托函数更新列表作为过滤器

The type or namespace name `T' could not be found. Are you missing a using directive or an assembly reference? 

这里缺少的是我的代码

using System; 
using System.Collections.Generic ; 
namespace test 
{ 
    class MainClass 
    { 
     public static List< mycapsule<int,double> > sample= new List< mycapsule<int,double>>(); 
     public static void Main (string[] args) 
     { 

      sample.Add(new mycapsule<int,double> {id=1 , value= 1.2}); 
      update(pred, 12.3); 
     } 

     public static bool pred(double x) 
     { 
      if (x==2.5) return true; 
      return false; 
     } 
     public class mycapsule<KT, T> 
     { 
      public KT id {get ; set; } 
      public T value { get ; set; } 
      public int p; // and more 

     }  

     public bool update(Func<T, bool> predicate, T i) 
     { 
      foreach (var x in sample.FindAll(item => predicate(JustValue(item)))) 
      { 
       x.value = i ; 
      } 
      return true ; 
     } 



     public T JustValue(mycapsule<int,T> i) 
     { 
      return i.value; 
     } 

    } 
} 
+1

在更新功能,什么是KeyRecord?它应该不是样本? – harshit

+0

是的,你是对的,我只是试图通过更改名称和删除无关的代码来简化它,但我错过了这一个 – user1654052

回答

0

这恐怕是行不通的,由于类型安全的原因。我纠正了代码,并尽可能得到这个:

public static List<mycapsule<int, double>> sample = new List<mycapsule<int, double>>(); 
public static void Main(string[] args) 
{ 
    sample.Add(new mycapsule<int, double> { id = 1, value = 1.2 }); 
    update(pred, 12.3); 
} 

public static bool pred(double x) 
{ 
    if (x == 2.5) return true; 
    return false; 
} 

public class mycapsule<KT, T> 
{ 
    public KT id { get; set; } 
    public T value { get; set; } 
    public int p; // and more 
} 

public static bool update<T>(Func<T, bool> predicate, T i) 
{ 
    List<mycapsule<int, double>> list = sample.FindAll(item => predicate(JustValue(item))); 
    foreach (var x in list) 
    { 
     x.value = i; 
    } 
    return true; 
} 

public static T JustValue<T>(mycapsule<int, T> i) 
{ 
    return i.value; 
} 

的错误是:

predicate(JustValue(item)) => Argument 1: cannot implicitly convert from double to T 

这源于一个事实,即你正在试图强行调用您指定的方法采用已知值为double的通用类型TFunc<T, bool>)。虽然我们知道T将是双从呼叫update(pred, 12.3);,没有什么能阻止我从传递一个谓词,采用不兼容的类型例如为:

public static bool pred(string x) 
{ 
    return false; 
} 

update(pred, "asdf"); 

这显然是不一致的。编译器只是试图防止你意外地在脚中射击自己。

为了解决这个问题,你可以明确地集合传递到更新method,从而确保该类型是一致的:

public static List<mycapsule<int, double>> sample = new List<mycapsule<int, double>>(); 
public static void Main(string[] args) 
{ 
    sample.Add(new mycapsule<int, double> { id = 1, value = 1.2 }); 
    update(pred, 12.5, sample); 
} 

public static bool pred(double x) 
{ 
    if (x == 2.5) return true; 
    return false; 
} 

public class mycapsule<KT, T> 
{ 
    public KT id { get; set; } 
    public T value { get; set; } 
    public int p; // and more 
} 

public static bool update<T>(Func<T, bool> predicate, T i, List<mycapsule<int, T>> list) 
{ 
    foreach (var x in list.FindAll(item => predicate(JustValue(item)))) 
    { 
     x.value = i; 
    } 
    return true; 
} 

public static T JustValue<T>(mycapsule<int, T> i) 
{ 
    return i.value; 
} 
+0

:S所以我们可以做些什么来防止不兼容的类型并解决这个问题。 – user1654052

+0

@ user1654052:看我的编辑。您可以将该列表作为参数添加到'update'方法以确保类型一致性。 – Tudor

+0

哇,太好了。现在它似乎工作,但性能问题呢:),它会实际上复制整个列表或它只是使用列表引用? – user1654052

2

看看你的更新方法:

public bool update(Func<T, bool> predicate, T i) 
{ 
    foreach (var x in KeyRecord.FindAll(item => predicate(JustValue(item)))) 
    { 
     x.value = i ; 
    } 
    return true ; 
} 

你期望T在这里?该方法不是通用的(它不会被编写为update<T>),也不会在泛型类中声明。

这是可能你只是想:

public bool update<T>(Func<T, bool> predicate, T i) 

...但很难不知道什么KeyRecord.FindAll样子说。噢,你的JustValue也有同样的问题。

作为一个侧面问题,方法名称updatepred不遵循.NET命名约定,并且JustValue在描述性方面是一个糟糕的方法名称。 mycapsule也不遵循.NET命名约定。在可读性方面,这些东西真的是问题

+0

谢谢,我刚刚删除了一些类并更改了名称(KeyRecord - > sample)。我现在会试试:) – user1654052

+0

我改变了你问的代码行,你可以试试这个,http://pastebin.com/Zrpm0cXH – user1654052

+0

@ user1654052:目前还不清楚你要做什么。你的'update'方法是通用的,但是你的列表总是*一个'List >'。 *为什么*你希望谓词在第一位通用? –

0

试试这个,对于泛型方法,你使用的方法定义是不正确的。
应该

//MethodName<T,U>(T para1, U para2) 

我修改了代码,包括反射,这应该工作。 请尝试并提供反馈。

using System; 
using System.Collections.Generic; 
using System.Reflection; 
namespace test 
{ 
    class MainClass 
    { 
     public static List<Mycapsule<int, double>> sample = new List<Mycapsule<int, double>>(); 

     public static void Main(string[] args) 
     { 

      sample.Add(new Mycapsule<int, double> { id = 1, value = 1.2 }); 
      update(pred, 12.3); 
     } 

     public static bool pred(double x) 
     { 
      if (x == 2.5) return true; 
      return false; 
     } 

     public static bool update<T>(Func<T, bool> predicate, T i) 
     { 
      var myCollection = sample.FindAll(p => pred(JustValue<double>(p))); 
      MainClass mainClass = new MainClass(); 
      foreach (var x in myCollection) 
      { 
       MethodInfo changeTypeMethod = typeof(MainClass).GetMethod("GetValue"); 
       object value = changeTypeMethod.Invoke(mainClass, new object[] { i, typeof(T) }); 
       PropertyInfo valueProperty = x.GetType().GetProperty("value"); 
       valueProperty.SetValue(x, value); 
      } 
      return true; 
     } 

     public T GetValue<T>(T i) 
     { 
      return (T)Convert.ChangeType(i, typeof(T)); 
     } 

     public static T JustValue<T>(Mycapsule<int, T> i) 
     { 
      return i.value; 
     } 
    } 
    //Outside the MainClass inside the same namespace 
    public class Mycapsule<KT, T> 
    { 
     public KT id { get; set; } 
     public T value { get; set; } 
     public int p; // and more 

    } 
} 
+0

1)你可以在另一个班级中有班级。 2)这不会编译。 – Tudor

+0

此代码编译,
我可能在类内部的类上出错了,但只要您正确定义KeyRecord,此代码就会编译。 –

+0

不为我编译:'predicate(JustValue(item)) - >参数1:无法从'double'转换为'T'' – Tudor