随笔 - 51  文章 - 0 评论 - 210 trackbacks - 6
<2007年12月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

严正声明 : 本站文章转载请注明出处.

与我联系

搜索

 

留言簿(11)

我的标签

随笔分类

随笔档案

Atlas相关

积分与排名

  • 积分 - 58801
  • 排名 - 800

阅读排行榜

这个问题本来发在社区里面,整理一下备以后参考.

public class TestClass : ITestInterface
    {
        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    
    }
    public interface ITestInterface
    {
        string Name { get; set;}
    }

为什么这样写就不行呢?

            IList<ITestInterface> list = (IList<ITestInterface>)new List<TestClass>();
            Assert.IsTrue(list != null);

我想使用实现相同接口的不同类型的集合类型, 这些类型又没有实现此接口的公共基类.


己想了一个解, 请大家看看吧.思想跟Klesh Wong的类似.

List<ClassA> listA = new List<ClassA>();
for (int i = 0; i < 10; i++)
{
ClassA a = new ClassA();
listA.Add(a);
}

List<ClassB> listB = new List<ClassB>();
for (int k = 0; k < 10; k++)
{
ClassB b = new ClassB();
listB.Add(b);
}
List<IMyInterface> listInterfaceA = listA.ConvertAll(new Converter<ClassA,IMyInterface>(ConterMyGenericClassA));
Assert.IsTrue(listInterfaceA.Count > 5);

List<IMyInterface> listInterfaceB = listB.ConvertAll(new Converter<ClassB, IMyInterface>(ConterMyGenericClassB));
Assert.IsTrue(listInterfaceB.Count > 5);
}
public static IMyInterface ConterMyGenericClassA(ClassA obj)
{
return (IMyInterface)obj;
}

public static IMyInterface ConterMyGenericClassB(ClassB obj)
{
return (IMyInterface)obj;
}

为 什么会有这种需求呢, 其实是这样. 通常我们会做一些控件,在里面公开一些数据源的属性,比如 IList<ClassA>, 而这里的数据我们有时候会去视图里面取出来, 如果采用把视图映射成对象的话我们就不能直接把这个源给到控件,当然,也并非不行,比如不使用泛型,就弄个ArrayList也行,但是俺们不是追求完美 嘛~~所以这个时候自然就想到抽象一个接口出来使这个控件的数据源不依赖于某个类型,这样我们在做数据访问的时候就省事多了,特别是使用了ORM组件的时 候.

再来个泛型加匿名代理的版本,一行就搞定了;)

List<IMyInterface> listE = listB.ConvertAll<IMyInterface>(new Converter<ClassB, IMyInterface>(delegate(ClassB b) { return (IMyInterface)b; }));
Assert.IsTrue(listE.Count > 0);


应该是这样写才比较靠谱:
IList<ITestInterface> list = new List<ITestInterface>();
在类型转换的时候,接口转换只针对实现接口的类型
而(IList<ITestInterface>)右侧的List<T>仅仅
[SerializableAttribute]
public class List<T> : IList<T>, ICollection<T>,
IEnumerable<T>, IList, ICollection, IEnumerable
而这里的T是强类型判断的,此时的T在编译时就已经被指定为TestClass,因此这里不存在一个类型转换的过程。
因此顶多只能(IList<TestClass>)new List<TestClass>();
而非(IList<ITestInterface>)new List<TestClass>();


1小时前   Klesh Wong :
理论上来,
IList<ITestInterface> list = (IList<ITestInterface>)new List<TestClass>();
这种写法应该是成立的才对,但确实又不能通过编译。
楼主的需求应该也有一定的合理性,暂时只能想出使用重新构建List的方法来做转换,不知各们有没有更好的解决方法?
IList<ITestInterface> list = Cast<TestClass, ITestInterface>(new List<TestClass>());
Response.Write(list != null);
public static IList<T> Cast<S, T>(IList<S> e) where S:T
{
IList<T> list = new List<T>();
foreach (S s in e)
list.Add(s);
return list;
}


posted on 2007-12-16 00:28 沙加 阅读(451) 评论(2)  编辑 收藏 网摘 所属分类: .Net开发技巧系列

FeedBack:
#1楼  2007-12-17 17:33 Arison [未注册用户]
public class TestMembers:IMembers
{
private string _name;
private int _age;

public int Age
{
get { return _age; }
set { _age = value; }
}

public string Name
{
get { return _name; }
set { _name = value; }
}
}
interface IMembers
{
string Name { get;set;}
}

class Program
{
static void Main(string[] args)
{
IList<IMembers> ls = new List<IMembers>();
TestMembers o = new TestMembers();
o.Name = "aa";
o.Age = 18;
ls.Add(o);

Console.Write(ls[0].Name);
}
}

不知道是不是这个意思?
  回复  引用    
#2楼 [楼主] 2007-12-18 13:59 沙加      
@Arison
这样当然也行, 不过开始的时候以为不可以呢,因为写到new List<IMembers>(); 这里的时候没有自动提示, 以为是不可行, 其实编译执行是没有问题的, 多谢
  回复  引用  查看    

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-12-16 00:31 编辑过
Google站内搜索


China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
近千种 9-95 新二手计算图书火热销售中!

相关文章:

相关链接: